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

All text for factions/towns/building are passed through translator

This commit is contained in:
Ivan Savenko 2023-01-04 15:17:50 +02:00
parent 388ed88b5d
commit 05a1d7c6e3
36 changed files with 230 additions and 153 deletions

View File

@ -1351,8 +1351,8 @@ bool AIGateway::moveHeroToTile(int3 dst, HeroPtr h)
void AIGateway::buildStructure(const CGTownInstance * t, BuildingID building) void AIGateway::buildStructure(const CGTownInstance * t, BuildingID building)
{ {
auto name = t->town->buildings.at(building)->Name(); auto name = t->town->buildings.at(building)->getNameTranslated();
logAi->debug("Player %d will build %s in town of %s at %s", ai->playerID, name, t->name, t->pos.toString()); logAi->debug("Player %d will build %s in town of %s at %s", ai->playerID, name, t->getNameTranslated(), t->pos.toString());
cb->buildBuilding(t, building); //just do this; cb->buildBuilding(t, building); //just do this;
} }

View File

@ -130,7 +130,7 @@ void BuildAnalyzer::update()
for(const CGTownInstance* town : towns) for(const CGTownInstance* town : towns)
{ {
logAi->trace("Checking town %s", town->name); logAi->trace("Checking town %s", town->getNameTranslated());
developmentInfos.push_back(TownDevelopmentInfo(town)); developmentInfos.push_back(TownDevelopmentInfo(town));
TownDevelopmentInfo & developmentInfo = developmentInfos.back(); TownDevelopmentInfo & developmentInfo = developmentInfos.back();
@ -351,7 +351,7 @@ BuildingInfo::BuildingInfo(
dailyIncome = building->produce; dailyIncome = building->produce;
exists = town->hasBuilt(id); exists = town->hasBuilt(id);
prerequisitesCount = 1; prerequisitesCount = 1;
name = building->Name(); name = building->getNameTranslated();
if(creature) if(creature)
{ {

View File

@ -50,14 +50,14 @@ Goals::TGoalVec DefenceBehavior::decompose() const
void DefenceBehavior::evaluateDefence(Goals::TGoalVec & tasks, const CGTownInstance * town) const void DefenceBehavior::evaluateDefence(Goals::TGoalVec & tasks, const CGTownInstance * town) const
{ {
logAi->trace("Evaluating defence for %s", town->name); logAi->trace("Evaluating defence for %s", town->getNameTranslated());
auto treatNode = ai->nullkiller->dangerHitMap->getObjectTreat(town); auto treatNode = ai->nullkiller->dangerHitMap->getObjectTreat(town);
auto treats = { treatNode.fastestDanger, treatNode.maximumDanger }; auto treats = { treatNode.fastestDanger, treatNode.maximumDanger };
if(!treatNode.fastestDanger.hero) if(!treatNode.fastestDanger.hero)
{ {
logAi->trace("No treat found for town %s", town->name); logAi->trace("No treat found for town %s", town->getNameTranslated());
return; return;
} }
@ -79,7 +79,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->getNameTranslated(), town->garrisonHero->getNameTranslated(),
town->name); town->getNameTranslated());
return; return;
} }
@ -88,7 +88,7 @@ void DefenceBehavior::evaluateDefence(Goals::TGoalVec & tasks, const CGTownInsta
if(reinforcement) if(reinforcement)
{ {
logAi->trace("Town %s can buy defence army %lld", town->name, reinforcement); logAi->trace("Town %s can buy defence army %lld", town->getNameTranslated(), reinforcement);
tasks.push_back(Goals::sptr(Goals::BuyArmy(town, reinforcement).setpriority(0.5f))); tasks.push_back(Goals::sptr(Goals::BuyArmy(town, reinforcement).setpriority(0.5f)));
} }
@ -98,7 +98,7 @@ void DefenceBehavior::evaluateDefence(Goals::TGoalVec & tasks, const CGTownInsta
{ {
logAi->trace( logAi->trace(
"Town %s has treat %lld in %s turns, hero: %s", "Town %s has treat %lld in %s turns, hero: %s",
town->name, town->getNameTranslated(),
treat.danger, treat.danger,
std::to_string(treat.turn), std::to_string(treat.turn),
treat.hero->getNameTranslated()); treat.hero->getNameTranslated());
@ -187,7 +187,7 @@ void DefenceBehavior::evaluateDefence(Goals::TGoalVec & tasks, const CGTownInsta
if(paths.empty()) if(paths.empty())
{ {
logAi->trace("No ways to defend town %s", town->name); logAi->trace("No ways to defend town %s", town->getNameTranslated());
continue; continue;
} }

View File

@ -46,7 +46,7 @@ bool BuildThis::operator==(const BuildThis & other) const
std::string BuildThis::toString() const std::string BuildThis::toString() const
{ {
return "Build " + buildingInfo.name + " in " + town->name; return "Build " + buildingInfo.name + " in " + town->getNameTranslated();
} }
void BuildThis::accept(AIGateway * ai) void BuildThis::accept(AIGateway * ai)
@ -58,7 +58,7 @@ void BuildThis::accept(AIGateway * ai)
if(cb->canBuildStructure(town, b) == EBuildingState::ALLOWED) if(cb->canBuildStructure(town, b) == EBuildingState::ALLOWED)
{ {
logAi->debug("Player %d will build %s in town of %s at %s", logAi->debug("Player %d will build %s in town of %s at %s",
ai->playerID, town->town->buildings.at(b)->Name(), town->name, town->pos.toString()); ai->playerID, town->town->buildings.at(b)->getNameTranslated(), town->getNameTranslated(), town->pos.toString());
cb->buildBuilding(town, b); cb->buildBuilding(town, b);
return; return;

View File

@ -29,7 +29,7 @@ bool BuyArmy::operator==(const BuyArmy & other) const
std::string BuyArmy::toString() const std::string BuyArmy::toString() const
{ {
return "Buy army at " + town->name; return "Buy army at " + town->getNameTranslated();
} }
void BuyArmy::accept(AIGateway * ai) void BuyArmy::accept(AIGateway * ai)

View File

@ -33,7 +33,7 @@ ExchangeSwapTownHeroes::ExchangeSwapTownHeroes(
std::string ExchangeSwapTownHeroes::toString() const std::string ExchangeSwapTownHeroes::toString() const
{ {
return "Exchange and swap heroes of " + town->name; return "Exchange and swap heroes of " + town->getNameTranslated();
} }
bool ExchangeSwapTownHeroes::operator==(const ExchangeSwapTownHeroes & other) const bool ExchangeSwapTownHeroes::operator==(const ExchangeSwapTownHeroes & other) const
@ -60,7 +60,7 @@ void ExchangeSwapTownHeroes::accept(AIGateway * ai)
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->getNameTranslated(), town->name); logAi->debug("Extracted hero %s from garrison of %s", currentGarrisonHero->getNameTranslated(), town->getNameTranslated());
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->getNameTranslated(), town->name); logAi->debug("Put hero %s to garrison of %s", garrisonHero->getNameTranslated(), town->getNameTranslated());
} }
} }

View File

@ -26,7 +26,7 @@ using namespace Goals;
std::string RecruitHero::toString() const std::string RecruitHero::toString() const
{ {
return "Recruit hero at " + town->name; return "Recruit hero at " + town->getNameTranslated();
} }
void RecruitHero::accept(AIGateway * ai) void RecruitHero::accept(AIGateway * ai)
@ -40,7 +40,7 @@ void RecruitHero::accept(AIGateway * ai)
throw cannotFulfillGoalException("No town to recruit hero!"); throw cannotFulfillGoalException("No town to recruit hero!");
} }
logAi->debug("Trying to recruit a hero in %s at %s", t->name, t->visitablePos().toString()); logAi->debug("Trying to recruit a hero in %s at %s", t->getNameTranslated(), t->visitablePos().toString());
auto heroes = cb->getAvailableHeroes(t); auto heroes = cb->getAvailableHeroes(t);
@ -78,4 +78,4 @@ void RecruitHero::accept(AIGateway * ai)
ai->moveHeroToTile(t->visitablePos(), t->visitingHero.get()); ai->moveHeroToTile(t->visitablePos(), t->visitingHero.get());
} }
} }

View File

@ -34,7 +34,7 @@ void TownPortalAction::execute(const CGHeroInstance * hero) const
std::string TownPortalAction::toString() const std::string TownPortalAction::toString() const
{ {
return "Town Portal to " + target->name; return "Town Portal to " + target->getNameTranslated();
} }
/* /*
bool TownPortalAction::canAct(const CGHeroInstance * hero, const AIPathNode * source) const bool TownPortalAction::canAct(const CGHeroInstance * hero, const AIPathNode * source) const

View File

@ -463,5 +463,5 @@ TownGarrisonActor::TownGarrisonActor(const CGTownInstance * town, uint64_t chain
std::string TownGarrisonActor::toString() const std::string TownGarrisonActor::toString() const
{ {
return town->name; return town->getNameTranslated();
} }

View File

@ -41,5 +41,5 @@ TSubgoal BuyArmy::whatToDoToAchieve()
std::string BuyArmy::completeMessage() const std::string BuyArmy::completeMessage() const
{ {
return boost::format("Bought army of value %d in town of %s") % value, town->name; return boost::format("Bought army of value %d in town of %s") % value, town->getNameTranslated();
} }

View File

@ -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->getNameTranslated(), 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->getNameTranslated(), 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
@ -1997,8 +1997,8 @@ bool VCAI::moveHeroToTile(int3 dst, HeroPtr h)
void VCAI::buildStructure(const CGTownInstance * t, BuildingID building) void VCAI::buildStructure(const CGTownInstance * t, BuildingID building)
{ {
auto name = t->town->buildings.at(building)->Name(); auto name = t->town->buildings.at(building)->getNameTranslated();
logAi->debug("Player %d will build %s in town of %s at %s", ai->playerID, name, t->name, t->pos.toString()); logAi->debug("Player %d will build %s in town of %s at %s", ai->playerID, name, t->getNameTranslated(), t->pos.toString());
cb->buildBuilding(t, building); //just do this; cb->buildBuilding(t, building); //just do this;
} }
@ -2081,7 +2081,7 @@ void VCAI::tryRealize(Goals::BuildThis & g)
if (cb->canBuildStructure(t, b) == EBuildingState::ALLOWED) if (cb->canBuildStructure(t, b) == EBuildingState::ALLOWED)
{ {
logAi->debug("Player %d will build %s in town of %s at %s", logAi->debug("Player %d will build %s in town of %s at %s",
playerID, t->town->buildings.at(b)->Name(), t->name, t->pos.toString()); playerID, t->town->buildings.at(b)->getNameTranslated(), t->getNameTranslated(), t->pos.toString());
cb->buildBuilding(t, b); cb->buildBuilding(t, b);
throw goalFulfilledException(sptr(g)); throw goalFulfilledException(sptr(g));
} }
@ -2439,7 +2439,7 @@ void VCAI::checkHeroArmy(HeroPtr h)
void VCAI::recruitHero(const CGTownInstance * t, bool throwing) void VCAI::recruitHero(const CGTownInstance * t, bool throwing)
{ {
logAi->debug("Trying to recruit a hero in %s at %s", t->name, t->visitablePos().toString()); logAi->debug("Trying to recruit a hero in %s at %s", t->getNameTranslated(), t->visitablePos().toString());
auto heroes = cb->getAvailableHeroes(t); auto heroes = cb->getAvailableHeroes(t);
if(heroes.size()) if(heroes.size())

View File

@ -804,7 +804,7 @@ void StackQueue::update()
int32_t StackQueue::getSiegeShooterIconID() int32_t StackQueue::getSiegeShooterIconID()
{ {
return owner.siegeController->getSiegedTown()->town->faction->index; return owner.siegeController->getSiegedTown()->town->faction->getIndex();
} }
StackQueue::StackBox::StackBox(StackQueue * owner): StackQueue::StackBox::StackBox(StackQueue * owner):

View File

@ -65,7 +65,7 @@ std::string BattleSiegeController::getWallPieceImageName(EWallVisual::EWallVisua
{ {
case EWallVisual::BACKGROUND_WALL: case EWallVisual::BACKGROUND_WALL:
{ {
switch(town->town->faction->index) switch(town->town->faction->getIndex())
{ {
case ETownType::RAMPART: case ETownType::RAMPART:
case ETownType::NECROPOLIS: case ETownType::NECROPOLIS:
@ -135,8 +135,8 @@ bool BattleSiegeController::getWallPieceExistance(EWallVisual::EWallVisual what)
switch (what) switch (what)
{ {
case EWallVisual::MOAT: return town->hasBuilt(BuildingID::CITADEL) && town->town->faction->index != ETownType::TOWER; case EWallVisual::MOAT: return town->hasBuilt(BuildingID::CITADEL) && town->town->faction->getIndex() != ETownType::TOWER;
case EWallVisual::MOAT_BANK: return town->hasBuilt(BuildingID::CITADEL) && town->town->faction->index != ETownType::TOWER && town->town->faction->index != ETownType::NECROPOLIS; case EWallVisual::MOAT_BANK: return town->hasBuilt(BuildingID::CITADEL) && town->town->faction->getIndex() != ETownType::TOWER && town->town->faction->getIndex() != ETownType::NECROPOLIS;
case EWallVisual::KEEP_BATTLEMENT: return town->hasBuilt(BuildingID::CITADEL) && owner.curInt->cb->battleGetWallState(EWallPart::KEEP) != EWallState::DESTROYED; case EWallVisual::KEEP_BATTLEMENT: return town->hasBuilt(BuildingID::CITADEL) && owner.curInt->cb->battleGetWallState(EWallPart::KEEP) != EWallState::DESTROYED;
case EWallVisual::UPPER_BATTLEMENT: return town->hasBuilt(BuildingID::CASTLE) && owner.curInt->cb->battleGetWallState(EWallPart::UPPER_TOWER) != EWallState::DESTROYED; case EWallVisual::UPPER_BATTLEMENT: return town->hasBuilt(BuildingID::CASTLE) && owner.curInt->cb->battleGetWallState(EWallPart::UPPER_TOWER) != EWallState::DESTROYED;
case EWallVisual::BOTTOM_BATTLEMENT: return town->hasBuilt(BuildingID::CASTLE) && owner.curInt->cb->battleGetWallState(EWallPart::BOTTOM_TOWER) != EWallState::DESTROYED; case EWallVisual::BOTTOM_BATTLEMENT: return town->hasBuilt(BuildingID::CASTLE) && owner.curInt->cb->battleGetWallState(EWallPart::BOTTOM_TOWER) != EWallState::DESTROYED;

View File

@ -203,7 +203,7 @@ void CBonusSelection::createBonusesIcons()
picNumber = -1; picNumber = -1;
if(vstd::contains((*CGI->townh)[faction]->town->buildings, buildID)) if(vstd::contains((*CGI->townh)[faction]->town->buildings, buildID))
desc = (*CGI->townh)[faction]->town->buildings.find(buildID)->second->Name(); desc = (*CGI->townh)[faction]->town->buildings.find(buildID)->second->getNameTranslated();
break; break;
} }

View File

@ -184,7 +184,7 @@ std::string OptionsTab::CPlayerSettingsHelper::getName()
default: default:
{ {
auto factionIndex = settings.castle >= CGI->townh->size() ? 0 : settings.castle; auto factionIndex = settings.castle >= CGI->townh->size() ? 0 : settings.castle;
return (*CGI->townh)[factionIndex]->name; return (*CGI->townh)[factionIndex]->getNameTranslated();
} }
} }
} }

View File

@ -172,7 +172,7 @@ std::string CComponent::getDescription()
case spell: return (*CGI->spellh)[subtype]->getDescriptionTranslated(val); case spell: return (*CGI->spellh)[subtype]->getDescriptionTranslated(val);
case morale: return CGI->generaltexth->heroscrn[ 4 - (val>0) + (val<0)]; case morale: return CGI->generaltexth->heroscrn[ 4 - (val>0) + (val<0)];
case luck: return CGI->generaltexth->heroscrn[ 7 - (val>0) + (val<0)]; case luck: return CGI->generaltexth->heroscrn[ 7 - (val>0) + (val<0)];
case building: return (*CGI->townh)[subtype]->town->buildings[BuildingID(val)]->Description(); case building: return (*CGI->townh)[subtype]->town->buildings[BuildingID(val)]->getDescriptionTranslated();
case hero: return ""; case hero: return "";
case flag: return ""; case flag: return "";
} }
@ -228,10 +228,10 @@ std::string CComponent::getSubtitleInternal()
auto building = (*CGI->townh)[subtype]->town->buildings[BuildingID(val)]; auto building = (*CGI->townh)[subtype]->town->buildings[BuildingID(val)];
if(!building) if(!building)
{ {
logGlobal->error("Town of faction %s has no building #%d", (*CGI->townh)[subtype]->town->faction->name, val); logGlobal->error("Town of faction %s has no building #%d", (*CGI->townh)[subtype]->town->faction->getNameTranslated(), val);
return (boost::format("Missing building #%d") % val).str(); return (boost::format("Missing building #%d") % val).str();
} }
return building->Name(); return building->getNameTranslated();
} }
case hero: return ""; case hero: return "";
case flag: return CGI->generaltexth->capColors[subtype]; case flag: return CGI->generaltexth->capColors[subtype];

View File

@ -145,8 +145,8 @@ void CBuildingRect::clickRight(tribool down, bool previousState)
const CBuilding *bld = town->town->buildings.at(bid); const CBuilding *bld = town->town->buildings.at(bid);
if (bid < BuildingID::DWELL_FIRST) if (bid < BuildingID::DWELL_FIRST)
{ {
CRClickPopup::createAndPush(CInfoWindow::genText(bld->Name(), bld->Description()), CRClickPopup::createAndPush(CInfoWindow::genText(bld->getNameTranslated(), bld->getDescriptionTranslated()),
std::make_shared<CComponent>(CComponent::building, bld->town->faction->index, bld->bid)); std::make_shared<CComponent>(CComponent::building, bld->town->faction->getIndex(), bld->bid));
} }
else else
{ {
@ -235,7 +235,7 @@ std::string CBuildingRect::getSubtitle()//hover text for building
int bid = getBuilding()->bid; int bid = getBuilding()->bid;
if (bid<30)//non-dwellings - only buiding name if (bid<30)//non-dwellings - only buiding name
return town->town->buildings.at(getBuilding()->bid)->Name(); return town->town->buildings.at(getBuilding()->bid)->getNameTranslated();
else//dwellings - recruit %creature% else//dwellings - recruit %creature%
{ {
auto & availableCreatures = town->creatures[(bid-30)%GameConstants::CREATURES_PER_TOWN].second; auto & availableCreatures = town->creatures[(bid-30)%GameConstants::CREATURES_PER_TOWN].second;
@ -736,7 +736,7 @@ void CCastleBuildings::buildingClicked(BuildingID building, BuildingSubID::EBuil
if(town->visitingHero) if(town->visitingHero)
GH.pushIntT<CMarketplaceWindow>(town, town->visitingHero, EMarketMode::RESOURCE_ARTIFACT); GH.pushIntT<CMarketplaceWindow>(town, town->visitingHero, EMarketMode::RESOURCE_ARTIFACT);
else else
LOCPLINT->showInfoDialog(boost::str(boost::format(CGI->generaltexth->allTexts[273]) % b->Name())); //Only visiting heroes may use the %s. LOCPLINT->showInfoDialog(boost::str(boost::format(CGI->generaltexth->allTexts[273]) % b->getNameTranslated())); //Only visiting heroes may use the %s.
break; break;
case BuildingSubID::FOUNTAIN_OF_FORTUNE: case BuildingSubID::FOUNTAIN_OF_FORTUNE:
@ -747,7 +747,7 @@ void CCastleBuildings::buildingClicked(BuildingID building, BuildingSubID::EBuil
if(getHero()) if(getHero())
GH.pushIntT<CMarketplaceWindow>(town, getHero(), EMarketMode::CREATURE_RESOURCE); GH.pushIntT<CMarketplaceWindow>(town, getHero(), EMarketMode::CREATURE_RESOURCE);
else else
LOCPLINT->showInfoDialog(boost::str(boost::format(CGI->generaltexth->allTexts[273]) % b->Name())); //Only visiting heroes may use the %s. LOCPLINT->showInfoDialog(boost::str(boost::format(CGI->generaltexth->allTexts[273]) % b->getNameTranslated())); //Only visiting heroes may use the %s.
break; break;
case BuildingSubID::MAGIC_UNIVERSITY: case BuildingSubID::MAGIC_UNIVERSITY:
@ -801,7 +801,7 @@ void CCastleBuildings::enterBlacksmith(ArtifactID artifactID)
const CGHeroInstance *hero = town->visitingHero; const CGHeroInstance *hero = town->visitingHero;
if(!hero) if(!hero)
{ {
LOCPLINT->showInfoDialog(boost::str(boost::format(CGI->generaltexth->allTexts[273]) % town->town->buildings.find(BuildingID::BLACKSMITH)->second->Name())); LOCPLINT->showInfoDialog(boost::str(boost::format(CGI->generaltexth->allTexts[273]) % town->town->buildings.find(BuildingID::BLACKSMITH)->second->getNameTranslated()));
return; return;
} }
auto art = artifactID.toArtifact(CGI->artifacts()); auto art = artifactID.toArtifact(CGI->artifacts());
@ -815,7 +815,7 @@ void CCastleBuildings::enterBlacksmith(ArtifactID artifactID)
void CCastleBuildings::enterBuilding(BuildingID building) void CCastleBuildings::enterBuilding(BuildingID building)
{ {
std::vector<std::shared_ptr<CComponent>> comps(1, std::make_shared<CComponent>(CComponent::building, town->subID, building)); std::vector<std::shared_ptr<CComponent>> comps(1, std::make_shared<CComponent>(CComponent::building, town->subID, building));
LOCPLINT->showInfoDialog( town->town->buildings.find(building)->second->Description(), comps); LOCPLINT->showInfoDialog( town->town->buildings.find(building)->second->getDescriptionTranslated(), comps);
} }
void CCastleBuildings::enterCastleGate() void CCastleBuildings::enterCastleGate()
@ -831,7 +831,7 @@ void CCastleBuildings::enterCastleGate()
{ {
const CGTownInstance *t = Town; const CGTownInstance *t = Town;
if (t->id != this->town->id && t->visitingHero == nullptr && //another town, empty and this is if (t->id != this->town->id && t->visitingHero == nullptr && //another town, empty and this is
t->town->faction->index == town->town->faction->index && //the town of the same faction t->town->faction->getId() == town->town->faction->getId() && //the town of the same faction
t->hasBuilt(BuildingSubID::CASTLE_GATE)) //and the town has a castle gate t->hasBuilt(BuildingSubID::CASTLE_GATE)) //and the town has a castle gate
{ {
availableTowns.push_back(t->id.getNum());//add to the list availableTowns.push_back(t->id.getNum());//add to the list
@ -866,18 +866,18 @@ void CCastleBuildings::enterToTheQuickRecruitmentWindow()
void CCastleBuildings::enterFountain(const BuildingID & building, BuildingSubID::EBuildingSubID subID, BuildingID::EBuildingID upgrades) void CCastleBuildings::enterFountain(const BuildingID & building, BuildingSubID::EBuildingSubID subID, BuildingID::EBuildingID upgrades)
{ {
std::vector<std::shared_ptr<CComponent>> comps(1, std::make_shared<CComponent>(CComponent::building,town->subID,building)); std::vector<std::shared_ptr<CComponent>> comps(1, std::make_shared<CComponent>(CComponent::building,town->subID,building));
std::string descr = town->town->buildings.find(building)->second->Description(); std::string descr = town->town->buildings.find(building)->second->getDescriptionTranslated();
std::string hasNotProduced; std::string hasNotProduced;
std::string hasProduced; std::string hasProduced;
if(this->town->town->faction->index == (TFaction)ETownType::RAMPART) if(this->town->town->faction->getIndex() == (TFaction)ETownType::RAMPART)
{ {
hasNotProduced = CGI->generaltexth->allTexts[677]; hasNotProduced = CGI->generaltexth->allTexts[677];
hasProduced = CGI->generaltexth->allTexts[678]; hasProduced = CGI->generaltexth->allTexts[678];
} }
else else
{ {
auto buildingName = town->town->getSpecialBuilding(subID)->Name(); auto buildingName = town->town->getSpecialBuilding(subID)->getNameTranslated();
hasNotProduced = std::string(CGI->generaltexth->translate("vcmi.townHall.hasNotProduced")); hasNotProduced = std::string(CGI->generaltexth->translate("vcmi.townHall.hasNotProduced"));
hasProduced = std::string(CGI->generaltexth->translate("vcmi.townHall.hasProduced")); hasProduced = std::string(CGI->generaltexth->translate("vcmi.townHall.hasProduced"));
@ -890,7 +890,7 @@ void CCastleBuildings::enterFountain(const BuildingID & building, BuildingSubID:
&& town->town->buildings.find(BuildingID(upgrades))->second->subId == BuildingSubID::MYSTIC_POND); && town->town->buildings.find(BuildingID(upgrades))->second->subId == BuildingSubID::MYSTIC_POND);
if(upgrades != BuildingID::NONE) if(upgrades != BuildingID::NONE)
descr += "\n\n"+town->town->buildings.find(BuildingID(upgrades))->second->Description(); descr += "\n\n"+town->town->buildings.find(BuildingID(upgrades))->second->getDescriptionTranslated();
if(isMysticPondOrItsUpgrade) //for vanila Rampart like towns if(isMysticPondOrItsUpgrade) //for vanila Rampart like towns
{ {
@ -1114,7 +1114,7 @@ void CTownInfo::hover(bool on)
if(on) if(on)
{ {
if(building ) if(building )
GH.statusbar->write(building->Name()); GH.statusbar->write(building->getNameTranslated());
} }
else else
{ {
@ -1126,8 +1126,8 @@ void CTownInfo::clickRight(tribool down, bool previousState)
{ {
if(building && down) if(building && down)
{ {
auto c = std::make_shared<CComponent>(CComponent::building, building->town->faction->index, building->bid); auto c = std::make_shared<CComponent>(CComponent::building, building->town->faction->getIndex(), building->bid);
CRClickPopup::createAndPush(CInfoWindow::genText(building->Name(), building->Description()), c); CRClickPopup::createAndPush(CInfoWindow::genText(building->getNameTranslated(), building->getDescriptionTranslated()), c);
} }
} }
@ -1152,7 +1152,7 @@ CCastleInterface::CCastleInterface(const CGTownInstance * Town, const CGTownInst
garr->type |= REDRAW_PARENT; garr->type |= REDRAW_PARENT;
heroes = std::make_shared<HeroSlots>(town, Point(241, 387), Point(241, 483), garr, true); heroes = std::make_shared<HeroSlots>(town, Point(241, 387), Point(241, 483), garr, true);
title = std::make_shared<CLabel>(85, 387, FONT_MEDIUM, ETextAlignment::TOPLEFT, Colors::WHITE, town->name); title = std::make_shared<CLabel>(85, 387, FONT_MEDIUM, ETextAlignment::TOPLEFT, Colors::WHITE, town->getNameTranslated());
income = std::make_shared<CLabel>(195, 443, FONT_SMALL, ETextAlignment::CENTER); income = std::make_shared<CLabel>(195, 443, FONT_SMALL, ETextAlignment::CENTER);
icon = std::make_shared<CAnimImage>("ITPT", 0, 0, 15, 387); icon = std::make_shared<CAnimImage>("ITPT", 0, 0, 15, 387);
@ -1316,7 +1316,7 @@ CHallInterface::CBuildingBox::CBuildingBox(int x, int y, const CGTownInstance *
header = std::make_shared<CAnimImage>("TPTHBAR", panelIndex[state], 0, 1, 73); header = std::make_shared<CAnimImage>("TPTHBAR", panelIndex[state], 0, 1, 73);
if(iconIndex[state] >=0) if(iconIndex[state] >=0)
mark = std::make_shared<CAnimImage>("TPTHCHK", iconIndex[state], 0, 136, 56); mark = std::make_shared<CAnimImage>("TPTHCHK", iconIndex[state], 0, 136, 56);
name = std::make_shared<CLabel>(75, 81, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE, building->Name()); name = std::make_shared<CLabel>(75, 81, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE, building->getNameTranslated());
//todo: add support for all possible states //todo: add support for all possible states
if(state >= EBuildingState::BUILDING_ERROR) if(state >= EBuildingState::BUILDING_ERROR)
@ -1334,7 +1334,7 @@ void CHallInterface::CBuildingBox::hover(bool on)
toPrint = CGI->generaltexth->allTexts[223]; toPrint = CGI->generaltexth->allTexts[223];
else else
toPrint = CGI->generaltexth->hcommands[state]; toPrint = CGI->generaltexth->hcommands[state];
boost::algorithm::replace_first(toPrint,"%s",building->Name()); boost::algorithm::replace_first(toPrint,"%s",building->getNameTranslated());
GH.statusbar->write(toPrint); GH.statusbar->write(toPrint);
} }
else else
@ -1368,7 +1368,7 @@ CHallInterface::CHallInterface(const CGTownInstance * Town):
auto statusbarBackground = std::make_shared<CPicture>(background->getSurface(), barRect, 5, 556, false); auto statusbarBackground = std::make_shared<CPicture>(background->getSurface(), barRect, 5, 556, false);
statusbar = CGStatusBar::create(statusbarBackground); statusbar = CGStatusBar::create(statusbarBackground);
title = std::make_shared<CLabel>(399, 12, FONT_MEDIUM, ETextAlignment::CENTER, Colors::WHITE, town->town->buildings.at(BuildingID(town->hallLevel()+BuildingID::VILLAGE_HALL))->Name()); title = std::make_shared<CLabel>(399, 12, FONT_MEDIUM, ETextAlignment::CENTER, Colors::WHITE, town->town->buildings.at(BuildingID(town->hallLevel()+BuildingID::VILLAGE_HALL))->getNameTranslated());
exit = std::make_shared<CButton>(Point(748, 556), "TPMAGE1.DEF", CButton::tooltip(CGI->generaltexth->hcommands[8]), [&](){close();}, SDLK_RETURN); exit = std::make_shared<CButton>(Point(748, 556), "TPMAGE1.DEF", CButton::tooltip(CGI->generaltexth->hcommands[8]), [&](){close();}, SDLK_RETURN);
exit->assignedKeys.insert(SDLK_ESCAPE); exit->assignedKeys.insert(SDLK_ESCAPE);
@ -1415,8 +1415,8 @@ CBuildWindow::CBuildWindow(const CGTownInstance *Town, const CBuilding * Buildin
auto statusbarBackground = std::make_shared<CPicture>(background->getSurface(), Rect(8, pos.h - 26, pos.w - 16, 19), 8, pos.h - 26); auto statusbarBackground = std::make_shared<CPicture>(background->getSurface(), Rect(8, pos.h - 26, pos.w - 16, 19), 8, pos.h - 26);
statusbar = CGStatusBar::create(statusbarBackground); statusbar = CGStatusBar::create(statusbarBackground);
name = std::make_shared<CLabel>(197, 30, FONT_MEDIUM, ETextAlignment::CENTER, Colors::WHITE, boost::str(boost::format(CGI->generaltexth->hcommands[7]) % building->Name())); name = std::make_shared<CLabel>(197, 30, FONT_MEDIUM, ETextAlignment::CENTER, Colors::WHITE, boost::str(boost::format(CGI->generaltexth->hcommands[7]) % building->getNameTranslated()));
description = std::make_shared<CTextBox>(building->Description(), Rect(33, 135, 329, 67), 0, FONT_MEDIUM, ETextAlignment::CENTER); description = std::make_shared<CTextBox>(building->getDescriptionTranslated(), Rect(33, 135, 329, 67), 0, FONT_MEDIUM, ETextAlignment::CENTER);
stateText = std::make_shared<CTextBox>(getTextForState(state), Rect(33, 216, 329, 67), 0, FONT_SMALL, ETextAlignment::CENTER); stateText = std::make_shared<CTextBox>(getTextForState(state), Rect(33, 216, 329, 67), 0, FONT_SMALL, ETextAlignment::CENTER);
//Create components for all required resources //Create components for all required resources
@ -1432,8 +1432,8 @@ CBuildWindow::CBuildWindow(const CGTownInstance *Town, const CBuilding * Buildin
if(!rightClick) if(!rightClick)
{ //normal window { //normal window
std::string tooltipYes = boost::str(boost::format(CGI->generaltexth->allTexts[595]) % building->Name()); std::string tooltipYes = boost::str(boost::format(CGI->generaltexth->allTexts[595]) % building->getNameTranslated());
std::string tooltipNo = boost::str(boost::format(CGI->generaltexth->allTexts[596]) % building->Name()); std::string tooltipNo = boost::str(boost::format(CGI->generaltexth->allTexts[596]) % building->getNameTranslated());
buy = std::make_shared<CButton>(Point(45, 446), "IBUY30", CButton::tooltip(tooltipYes), [&](){ buyFunc(); }, SDLK_RETURN); buy = std::make_shared<CButton>(Point(45, 446), "IBUY30", CButton::tooltip(tooltipYes), [&](){ buyFunc(); }, SDLK_RETURN);
buy->setBorderColor(Colors::METALLIC_GOLD); buy->setBorderColor(Colors::METALLIC_GOLD);
@ -1460,7 +1460,7 @@ std::string CBuildWindow::getTextForState(int state)
case EBuildingState::ALREADY_PRESENT: case EBuildingState::ALREADY_PRESENT:
case EBuildingState::CANT_BUILD_TODAY: case EBuildingState::CANT_BUILD_TODAY:
case EBuildingState::NO_RESOURCES: case EBuildingState::NO_RESOURCES:
ret.replace(ret.find_first_of("%s"), 2, building->Name()); ret.replace(ret.find_first_of("%s"), 2, building->getNameTranslated());
break; break;
case EBuildingState::ALLOWED: case EBuildingState::ALLOWED:
return CGI->generaltexth->allTexts[219]; //all prereq. are met return CGI->generaltexth->allTexts[219]; //all prereq. are met
@ -1468,7 +1468,7 @@ std::string CBuildWindow::getTextForState(int state)
{ {
auto toStr = [&](const BuildingID build) -> std::string auto toStr = [&](const BuildingID build) -> std::string
{ {
return town->town->buildings.at(build)->Name(); return town->town->buildings.at(build)->getNameTranslated();
}; };
ret = CGI->generaltexth->allTexts[52]; ret = CGI->generaltexth->allTexts[52];
@ -1478,7 +1478,7 @@ std::string CBuildWindow::getTextForState(int state)
case EBuildingState::MISSING_BASE: case EBuildingState::MISSING_BASE:
{ {
std::string msg = CGI->generaltexth->translate("vcmi.townHall.missingBase"); std::string msg = CGI->generaltexth->translate("vcmi.townHall.missingBase");
ret = boost::str(boost::format(msg) % town->town->buildings.at(building->upgrade)->Name()); ret = boost::str(boost::format(msg) % town->town->buildings.at(building->upgrade)->getNameTranslated());
break; break;
} }
} }
@ -1542,9 +1542,9 @@ CFortScreen::CFortScreen(const CGTownInstance * town):
fortSize--; fortSize--;
const CBuilding * fortBuilding = town->town->buildings.at(BuildingID(town->fortLevel()+6)); const CBuilding * fortBuilding = town->town->buildings.at(BuildingID(town->fortLevel()+6));
title = std::make_shared<CLabel>(400, 12, FONT_BIG, ETextAlignment::CENTER, Colors::WHITE, fortBuilding->Name()); title = std::make_shared<CLabel>(400, 12, FONT_BIG, ETextAlignment::CENTER, Colors::WHITE, fortBuilding->getNameTranslated());
std::string text = boost::str(boost::format(CGI->generaltexth->fcommands[6]) % fortBuilding->Name()); std::string text = boost::str(boost::format(CGI->generaltexth->fcommands[6]) % fortBuilding->getNameTranslated());
exit = std::make_shared<CButton>(Point(748, 556), "TPMAGE1", CButton::tooltip(text), [&](){ close(); }, SDLK_RETURN); exit = std::make_shared<CButton>(Point(748, 556), "TPMAGE1", CButton::tooltip(text), [&](){ close(); }, SDLK_RETURN);
exit->assignedKeys.insert(SDLK_ESCAPE); exit->assignedKeys.insert(SDLK_ESCAPE);
@ -1629,7 +1629,7 @@ CFortScreen::RecruitArea::RecruitArea(int posX, int posY, const CGTownInstance *
if(getMyBuilding() != nullptr) if(getMyBuilding() != nullptr)
{ {
buildingIcon = std::make_shared<CAnimImage>(town->town->clientInfo.buildingsIcons, getMyBuilding()->bid, 0, 4, 21); buildingIcon = std::make_shared<CAnimImage>(town->town->clientInfo.buildingsIcons, getMyBuilding()->bid, 0, 4, 21);
buildingName = std::make_shared<CLabel>(78, 101, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE, getMyBuilding()->Name()); buildingName = std::make_shared<CLabel>(78, 101, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE, getMyBuilding()->getNameTranslated());
if(vstd::contains(town->builtBuildings, getMyBuilding()->bid)) if(vstd::contains(town->builtBuildings, getMyBuilding()->bid))
{ {

View File

@ -767,7 +767,7 @@ CTownItem::CTownItem(const CGTownInstance * Town)
{ {
OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE); OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);
background = std::make_shared<CAnimImage>("OVSLOT", 6); background = std::make_shared<CAnimImage>("OVSLOT", 6);
name = std::make_shared<CLabel>(74, 8, FONT_SMALL, ETextAlignment::TOPLEFT, Colors::WHITE, town->name); name = std::make_shared<CLabel>(74, 8, FONT_SMALL, ETextAlignment::TOPLEFT, Colors::WHITE, town->getNameTranslated());
income = std::make_shared<CLabel>( 190, 60, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE, boost::lexical_cast<std::string>(town->dailyIncome()[Res::GOLD])); income = std::make_shared<CLabel>( 190, 60, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE, boost::lexical_cast<std::string>(town->dailyIncome()[Res::GOLD]));
hall = std::make_shared<CTownInfo>( 69, 31, town, true); hall = std::make_shared<CTownInfo>( 69, 31, town, true);

View File

@ -668,14 +668,14 @@ CMarketplaceWindow::CMarketplaceWindow(const IMarket * Market, const CGHeroInsta
switch (mode) switch (mode)
{ {
case EMarketMode::CREATURE_RESOURCE: case EMarketMode::CREATURE_RESOURCE:
title = (*CGI->townh)[ETownType::STRONGHOLD]->town->buildings[BuildingID::FREELANCERS_GUILD]->Name(); title = (*CGI->townh)[ETownType::STRONGHOLD]->town->buildings[BuildingID::FREELANCERS_GUILD]->getNameTranslated();
break; break;
case EMarketMode::RESOURCE_ARTIFACT: case EMarketMode::RESOURCE_ARTIFACT:
title = (*CGI->townh)[market->o->subID]->town->buildings[BuildingID::ARTIFACT_MERCHANT]->Name(); title = (*CGI->townh)[market->o->subID]->town->buildings[BuildingID::ARTIFACT_MERCHANT]->getNameTranslated();
sliderNeeded = false; sliderNeeded = false;
break; break;
case EMarketMode::ARTIFACT_RESOURCE: case EMarketMode::ARTIFACT_RESOURCE:
title = (*CGI->townh)[market->o->subID]->town->buildings[BuildingID::ARTIFACT_MERCHANT]->Name(); title = (*CGI->townh)[market->o->subID]->town->buildings[BuildingID::ARTIFACT_MERCHANT]->getNameTranslated();
// create image that copies part of background containing slot MISC_1 into position of slot MISC_5 // create image that copies part of background containing slot MISC_1 into position of slot MISC_5
// this is workaround for bug in H3 files where this slot for ragdoll on this screen is missing // this is workaround for bug in H3 files where this slot for ragdoll on this screen is missing

View File

@ -1586,7 +1586,7 @@ CUniversityWindow::CUniversityWindow(const CGHeroInstance * _hero, const IMarket
if(town) if(town)
{ {
auto faction = town->town->faction->index; auto faction = town->town->faction->getId();
auto bid = town->town->getSpecialBuilding(BuildingSubID::MAGIC_UNIVERSITY)->bid; auto bid = town->town->getSpecialBuilding(BuildingSubID::MAGIC_UNIVERSITY)->bid;
titlePic = std::make_shared<CAnimImage>((*CGI->townh)[faction]->town->clientInfo.buildingsIcons, bid); titlePic = std::make_shared<CAnimImage>((*CGI->townh)[faction]->town->clientInfo.buildingsIcons, bid);
} }

View File

@ -18,8 +18,12 @@ class FactionID;
class DLL_LINKAGE Faction : public EntityT<FactionID> class DLL_LINKAGE Faction : public EntityT<FactionID>
{ {
using EntityT<FactionID>::getName;
public: public:
virtual bool hasTown() const = 0; virtual bool hasTown() const = 0;
virtual std::string getNameTranslated() const = 0;
virtual std::string getNameTextID() const = 0;
}; };
VCMI_LIB_NAMESPACE_END VCMI_LIB_NAMESPACE_END

View File

@ -328,7 +328,7 @@ CGHeroInstance * CGameState::HeroesPool::pickHeroFor(bool native, PlayerColor pl
if(player>=PlayerColor::PLAYER_LIMIT) if(player>=PlayerColor::PLAYER_LIMIT)
{ {
logGlobal->error("Cannot pick hero for faction %d. Wrong owner!", town->faction->index); logGlobal->error("Cannot pick hero for faction %s. Wrong owner!", town->faction->getJsonKey());
return nullptr; return nullptr;
} }
@ -339,7 +339,7 @@ CGHeroInstance * CGameState::HeroesPool::pickHeroFor(bool native, PlayerColor pl
for(auto & elem : available) for(auto & elem : available)
{ {
if(pavailable.find(elem.first)->second & 1<<player.getNum() if(pavailable.find(elem.first)->second & 1<<player.getNum()
&& elem.second->type->heroClass->faction == town->faction->index) && elem.second->type->heroClass->faction == town->faction->getIndex())
{ {
pool.push_back(elem.second); //get all available heroes pool.push_back(elem.second); //get all available heroes
} }
@ -364,7 +364,7 @@ CGHeroInstance * CGameState::HeroesPool::pickHeroFor(bool native, PlayerColor pl
( !bannedClass || elem.second->type->heroClass != bannedClass) ) // and his class is not same as other hero ( !bannedClass || elem.second->type->heroClass != bannedClass) ) // and his class is not same as other hero
{ {
pool.push_back(elem.second); pool.push_back(elem.second);
sum += elem.second->type->heroClass->selectionProbability[town->faction->index]; //total weight sum += elem.second->type->heroClass->selectionProbability[town->faction->getIndex()]; //total weight
} }
} }
if(!pool.size() || sum == 0) if(!pool.size() || sum == 0)
@ -376,7 +376,7 @@ CGHeroInstance * CGameState::HeroesPool::pickHeroFor(bool native, PlayerColor pl
r = rand.nextInt(sum - 1); r = rand.nextInt(sum - 1);
for (auto & elem : pool) for (auto & elem : pool)
{ {
r -= elem->type->heroClass->selectionProbability[town->faction->index]; r -= elem->type->heroClass->selectionProbability[town->faction->getIndex()];
if(r < 0) if(r < 0)
{ {
ret = elem; ret = elem;
@ -623,7 +623,7 @@ std::pair<Obj,int> CGameState::pickObject (CGObjectInstance *obj)
if (result.first == Obj::NO_OBJ) if (result.first == Obj::NO_OBJ)
{ {
logGlobal->error("Error: failed to find dwelling for %s of level %d", (*VLC->townh)[faction]->name, int(level)); logGlobal->error("Error: failed to find dwelling for %s of level %d", (*VLC->townh)[faction]->getNameTranslated(), int(level));
result = std::make_pair(Obj::CREATURE_GENERATOR1, *RandomGeneratorUtil::nextItem(VLC->objtypeh->knownSubObjects(Obj::CREATURE_GENERATOR1), getRandomGenerator())); result = std::make_pair(Obj::CREATURE_GENERATOR1, *RandomGeneratorUtil::nextItem(VLC->objtypeh->knownSubObjects(Obj::CREATURE_GENERATOR1), getRandomGenerator()));
} }
@ -1711,9 +1711,10 @@ void CGameState::initTowns()
{ {
vti->town = (*VLC->townh)[vti->subID]->town; vti->town = (*VLC->townh)[vti->subID]->town;
} }
if(vti->name.empty()) if(vti->getNameTranslated().empty())
{ {
vti->name = *RandomGeneratorUtil::nextItem(vti->town->names, getRandomGenerator()); size_t nameID = getRandomGenerator().nextInt(vti->town->getRandomNamesCount());
vti->setNameTranslated(vti->town->getRandomNameTranslated(nameID));
} }
//init buildings //init buildings
@ -3076,7 +3077,7 @@ void InfoAboutTown::initFromTown(const CGTownInstance *t, bool detailed)
army = ArmyDescriptor(t->getUpperArmy(), detailed); army = ArmyDescriptor(t->getUpperArmy(), detailed);
built = t->builded; built = t->builded;
fortLevel = t->fortLevel(); fortLevel = t->fortLevel();
name = t->name; name = t->getNameTranslated();
tType = t->town; tType = t->town;
vstd::clear_pointer(details); vstd::clear_pointer(details);

View File

@ -364,11 +364,11 @@ void CHeroClassHandler::afterLoadFinalization()
{ {
if (!faction->town) if (!faction->town)
continue; continue;
if (heroClass->selectionProbability.count(faction->index)) if (heroClass->selectionProbability.count(faction->getIndex()))
continue; continue;
float chance = static_cast<float>(heroClass->defaultTavernChance * faction->town->defaultTavernChance); float chance = static_cast<float>(heroClass->defaultTavernChance * faction->town->defaultTavernChance);
heroClass->selectionProbability[faction->index] = static_cast<int>(sqrt(chance) + 0.5); //FIXME: replace with std::round once MVS supports it heroClass->selectionProbability[faction->getIndex()] = static_cast<int>(sqrt(chance) + 0.5); //FIXME: replace with std::round once MVS supports it
} }
// set default probabilities for gaining secondary skills where not loaded previously // set default probabilities for gaining secondary skills where not loaded previously
heroClass->secSkillProbability.resize(VLC->skillh->size(), -1); heroClass->secSkillProbability.resize(VLC->skillh->size(), -1);

View File

@ -44,14 +44,29 @@ const std::map<std::string, CBuilding::ETowerHeight> CBuilding::TOWER_TYPES =
{ "skyship", CBuilding::HEIGHT_SKYSHIP } { "skyship", CBuilding::HEIGHT_SKYSHIP }
}; };
const std::string & CBuilding::Name() const std::string CBuilding::getJsonKey() const
{ {
return name; return identifier;
} }
const std::string & CBuilding::Description() const std::string CBuilding::getNameTranslated() const
{ {
return description; return VLC->generaltexth->translate(getNameTextID());
}
std::string CBuilding::getDescriptionTranslated() const
{
return VLC->generaltexth->translate(getDescriptionTextID());
}
std::string CBuilding::getNameTextID() const
{
return TextIdentifier("building", town->faction->getJsonKey(), modScope, identifier, "name").get();
}
std::string CBuilding::getDescriptionTextID() const
{
return TextIdentifier("building", town->faction->getJsonKey(), modScope, identifier, "description").get();
} }
BuildingID CBuilding::getBase() const BuildingID CBuilding::getBase() const
@ -109,7 +124,7 @@ int32_t CFaction::getIconIndex() const
const std::string & CFaction::getName() const const std::string & CFaction::getName() const
{ {
return name; return identifier;
} }
const std::string & CFaction::getJsonKey() const const std::string & CFaction::getJsonKey() const
@ -138,6 +153,16 @@ void CFaction::registerIcons(const IconRegistar & cb) const
} }
} }
std::string CFaction::getNameTranslated() const
{
return VLC->generaltexth->translate(getNameTextID());
}
std::string CFaction::getNameTextID() const
{
return TextIdentifier("faction", modScope, identifier, "name").get();
}
FactionID CFaction::getId() const FactionID CFaction::getId() const
{ {
return FactionID(index); return FactionID(index);
@ -173,12 +198,19 @@ CTown::~CTown()
str.dellNull(); str.dellNull();
} }
std::string CTown::getLocalizedFactionName() const std::string CTown::getRandomNameTranslated(size_t index) const
{ {
if(faction == nullptr) return VLC->generaltexth->translate(getRandomNameTextID(index));
return "Random"; }
else
return faction->name; std::string CTown::getRandomNameTextID(size_t index) const
{
return TextIdentifier("faction", faction->getJsonKey(), "randomName", index).get();
}
size_t CTown::getRandomNamesCount() const
{
return namesCount;
} }
std::string CTown::getBuildingScope() const std::string CTown::getBuildingScope() const
@ -187,7 +219,7 @@ std::string CTown::getBuildingScope() const
//no faction == random faction //no faction == random faction
return "building"; return "building";
else else
return "building." + faction->identifier; return "building." + faction->getJsonKey();
} }
std::set<si32> CTown::getAllBuildings() const std::set<si32> CTown::getAllBuildings() const
@ -231,6 +263,11 @@ void CTown::setGreeting(BuildingSubID::EBuildingSubID subID, const std::string m
CTownHandler::CTownHandler() CTownHandler::CTownHandler()
{ {
randomTown = new CTown(); randomTown = new CTown();
randomFaction = new CFaction();
randomFaction->town = randomTown;
randomTown->faction = randomFaction;
randomFaction->identifier = "random";
randomFaction->modScope = "core";
} }
CTownHandler::~CTownHandler() CTownHandler::~CTownHandler()
@ -460,10 +497,10 @@ void CTownHandler::addBonusesForVanilaBuilding(CBuilding * building)
} }
else if(building->bid == BuildingID::GRAIL else if(building->bid == BuildingID::GRAIL
&& building->town->faction != nullptr && building->town->faction != nullptr
&& boost::algorithm::ends_with(building->town->faction->identifier, ":cove")) && boost::algorithm::ends_with(building->town->faction->getJsonKey(), ":cove"))
{ {
static TPropagatorPtr allCreaturesPropagator(new CPropagatorNodeType(CBonusSystemNode::ENodeTypes::ALL_CREATURES)); static TPropagatorPtr allCreaturesPropagator(new CPropagatorNodeType(CBonusSystemNode::ENodeTypes::ALL_CREATURES));
static auto factionLimiter = std::make_shared<CreatureFactionLimiter>(building->town->faction->index); static auto factionLimiter = std::make_shared<CreatureFactionLimiter>(building->town->faction->getIndex());
b = createBonus(building, Bonus::NO_TERRAIN_PENALTY, 0, allCreaturesPropagator); b = createBonus(building, Bonus::NO_TERRAIN_PENALTY, 0, allCreaturesPropagator);
b->addLimiter(factionLimiter); b->addLimiter(factionLimiter);
} }
@ -505,7 +542,7 @@ std::shared_ptr<Bonus> CTownHandler::createBonus(CBuilding * build, Bonus::Bonus
std::shared_ptr<Bonus> CTownHandler::createBonus(CBuilding * build, Bonus::BonusType type, int val, TPropagatorPtr & prop, int subtype) std::shared_ptr<Bonus> CTownHandler::createBonus(CBuilding * build, Bonus::BonusType type, int val, TPropagatorPtr & prop, int subtype)
{ {
std::ostringstream descr; std::ostringstream descr;
descr << build->name; descr << build->getNameTranslated();
return createBonusImpl(build->bid, type, val, prop, descr.str(), subtype); return createBonusImpl(build->bid, type, val, prop, descr.str(), subtype);
} }
@ -523,7 +560,7 @@ void CTownHandler::loadSpecialBuildingBonuses(const JsonNode & source, BonusList
{ {
for(auto b : source.Vector()) for(auto b : source.Vector())
{ {
auto bonus = JsonUtils::parseBuildingBonus(b, building->bid, building->name); auto bonus = JsonUtils::parseBuildingBonus(b, building->bid, building->getNameTranslated());
if(bonus == nullptr) if(bonus == nullptr)
continue; continue;
@ -533,7 +570,7 @@ void CTownHandler::loadSpecialBuildingBonuses(const JsonNode & source, BonusList
auto limPtr = dynamic_cast<CreatureFactionLimiter*>(bonus->limiter.get()); auto limPtr = dynamic_cast<CreatureFactionLimiter*>(bonus->limiter.get());
if(limPtr != nullptr && limPtr->faction == (TFaction)-1) if(limPtr != nullptr && limPtr->faction == (TFaction)-1)
limPtr->faction = building->town->faction->index; limPtr->faction = building->town->faction->getIndex();
} }
//JsonUtils::parseBuildingBonus produces UNKNOWN type propagator instead of empty. //JsonUtils::parseBuildingBonus produces UNKNOWN type propagator instead of empty.
if(bonus->propagator != nullptr if(bonus->propagator != nullptr
@ -567,8 +604,10 @@ void CTownHandler::loadBuilding(CTown * town, const std::string & stringID, cons
ret->identifier = stringID; ret->identifier = stringID;
ret->town = town; ret->town = town;
ret->name = source["name"].String();
ret->description = source["description"].String(); VLC->generaltexth->registerString(ret->getNameTextID(), source["name"].String());
VLC->generaltexth->registerString(ret->getDescriptionTextID(), source["description"].String());
ret->resources = TResources(source["cost"]); ret->resources = TResources(source["cost"]);
ret->produce = TResources(source["produce"]); ret->produce = TResources(source["produce"]);
@ -589,7 +628,7 @@ void CTownHandler::loadBuilding(CTown * town, const std::string & stringID, cons
ret->subId = BuildingSubID::CUSTOM_VISITING_BONUS; ret->subId = BuildingSubID::CUSTOM_VISITING_BONUS;
for(auto & bonus : ret->onVisitBonuses) for(auto & bonus : ret->onVisitBonuses)
bonus->sid = Bonus::getSid32(ret->town->faction->index, ret->bid); bonus->sid = Bonus::getSid32(ret->town->faction->getIndex(), ret->bid);
} }
} }
//MODS COMPATIBILITY FOR 0.96 //MODS COMPATIBILITY FOR 0.96
@ -630,7 +669,7 @@ void CTownHandler::loadBuilding(CTown * town, const std::string & stringID, cons
if(stringID == source["upgrades"].String()) if(stringID == source["upgrades"].String())
{ {
throw std::runtime_error(boost::str(boost::format("Building with ID '%s' of town '%s' can't be an upgrade of the same building.") % throw std::runtime_error(boost::str(boost::format("Building with ID '%s' of town '%s' can't be an upgrade of the same building.") %
stringID % ret->town->getLocalizedFactionName())); stringID % ret->town->faction->getNameTranslated()));
} }
VLC->modh->identifiers.requestIdentifier(ret->town->getBuildingScope(), source["upgrades"], [=](si32 identifier) VLC->modh->identifiers.requestIdentifier(ret->town->getBuildingScope(), source["upgrades"], [=](si32 identifier)
@ -664,21 +703,21 @@ void CTownHandler::loadStructure(CTown &town, const std::string & stringID, cons
ret->building = nullptr; ret->building = nullptr;
ret->buildable = nullptr; ret->buildable = nullptr;
VLC->modh->identifiers.tryRequestIdentifier( source.meta, "building." + town.faction->identifier, stringID, [=, &town](si32 identifier) mutable VLC->modh->identifiers.tryRequestIdentifier( source.meta, "building." + town.faction->getJsonKey(), stringID, [=, &town](si32 identifier) mutable
{ {
ret->building = town.buildings[BuildingID(identifier)]; ret->building = town.buildings[BuildingID(identifier)];
}); });
if (source["builds"].isNull()) if (source["builds"].isNull())
{ {
VLC->modh->identifiers.tryRequestIdentifier( source.meta, "building." + town.faction->identifier, stringID, [=, &town](si32 identifier) mutable VLC->modh->identifiers.tryRequestIdentifier( source.meta, "building." + town.faction->getJsonKey(), stringID, [=, &town](si32 identifier) mutable
{ {
ret->building = town.buildings[BuildingID(identifier)]; ret->building = town.buildings[BuildingID(identifier)];
}); });
} }
else else
{ {
VLC->modh->identifiers.requestIdentifier("building." + town.faction->identifier, source["builds"], [=, &town](si32 identifier) mutable VLC->modh->identifiers.requestIdentifier("building." + town.faction->getJsonKey(), source["builds"], [=, &town](si32 identifier) mutable
{ {
ret->buildable = town.buildings[BuildingID(identifier)]; ret->buildable = town.buildings[BuildingID(identifier)];
}); });
@ -729,7 +768,7 @@ void CTownHandler::loadTownHall(CTown &town, const JsonNode & source)
auto & dst = dstBox[k]; auto & dst = dstBox[k];
auto & src = srcBox[k]; auto & src = srcBox[k];
VLC->modh->identifiers.requestIdentifier("building." + town.faction->identifier, src, [&](si32 identifier) VLC->modh->identifiers.requestIdentifier("building." + town.faction->getJsonKey(), src, [&](si32 identifier)
{ {
dst = BuildingID(identifier); dst = BuildingID(identifier);
}); });
@ -757,7 +796,7 @@ void CTownHandler::loadSiegeScreen(CTown &town, const JsonNode & source)
auto crId = CreatureID(creature); auto crId = CreatureID(creature);
if(!(*VLC->creh)[crId]->animation.missleFrameAngles.size()) if(!(*VLC->creh)[crId]->animation.missleFrameAngles.size())
logMod->error("Mod '%s' error: Creature '%s' on the Archer's tower is not a shooter. Mod should be fixed. Siege will not work properly!" logMod->error("Mod '%s' error: Creature '%s' on the Archer's tower is not a shooter. Mod should be fixed. Siege will not work properly!"
, town.faction->name , town.faction->getNameTranslated()
, (*VLC->creh)[crId]->getNameSingularTranslated()); , (*VLC->creh)[crId]->getNameSingularTranslated());
town.clientInfo.siegeShooter = crId; town.clientInfo.siegeShooter = crId;
@ -848,7 +887,13 @@ void CTownHandler::loadTown(CTown * town, const JsonNode & source)
town->moatHexes = source["moatHexes"].convertTo<std::vector<BattleHex> >(); town->moatHexes = source["moatHexes"].convertTo<std::vector<BattleHex> >();
town->mageLevel = static_cast<ui32>(source["mageGuild"].Float()); town->mageLevel = static_cast<ui32>(source["mageGuild"].Float());
town->names = source["names"].convertTo<std::vector<std::string> >();
town->namesCount = 0;
for (auto const & name : source["names"].Vector())
{
VLC->generaltexth->registerString(town->getRandomNameTextID(town->namesCount), name.String());
town->namesCount += 1;
}
// Horde building creature level // Horde building creature level
for(const JsonNode &node : source["horde"].Vector()) for(const JsonNode &node : source["horde"].Vector())
@ -886,7 +931,7 @@ void CTownHandler::loadTown(CTown * town, const JsonNode & source)
VLC->modh->identifiers.requestIdentifier(node.second.meta, "heroClass",node.first, [=](si32 classID) VLC->modh->identifiers.requestIdentifier(node.second.meta, "heroClass",node.first, [=](si32 classID)
{ {
VLC->heroh->classes[HeroClassID(classID)]->selectionProbability[town->faction->index] = chance; VLC->heroh->classes[HeroClassID(classID)]->selectionProbability[town->faction->getIndex()] = chance;
}); });
} }
@ -896,7 +941,7 @@ void CTownHandler::loadTown(CTown * town, const JsonNode & source)
VLC->modh->identifiers.requestIdentifier(node.second.meta, "spell", node.first, [=](si32 spellID) VLC->modh->identifiers.requestIdentifier(node.second.meta, "spell", node.first, [=](si32 spellID)
{ {
VLC->spellh->objects.at(spellID)->probabilities[town->faction->index] = chance; VLC->spellh->objects.at(spellID)->probabilities[town->faction->getIndex()] = chance;
}); });
} }
@ -941,9 +986,11 @@ CFaction * CTownHandler::loadFromJson(const std::string & scope, const JsonNode
auto faction = new CFaction(); auto faction = new CFaction();
faction->index = static_cast<TFaction>(index); faction->index = static_cast<TFaction>(index);
faction->name = source["name"].String(); faction->modScope = scope;
faction->identifier = identifier; faction->identifier = identifier;
VLC->generaltexth->registerString(faction->getNameTextID(), source["name"].String());
faction->creatureBg120 = source["creatureBackground"]["120px"].String(); faction->creatureBg120 = source["creatureBackground"]["120px"].String();
faction->creatureBg130 = source["creatureBackground"]["130px"].String(); faction->creatureBg130 = source["creatureBackground"]["130px"].String();

View File

@ -38,9 +38,8 @@ class JsonSerializeFormat;
class DLL_LINKAGE CBuilding class DLL_LINKAGE CBuilding
{ {
std::string modScope;
std::string name; std::string identifier;
std::string description;
public: public:
typedef LogicalExpression<BuildingID> TRequired; typedef LogicalExpression<BuildingID> TRequired;
@ -49,7 +48,6 @@ public:
TResources resources; TResources resources;
TResources produce; TResources produce;
TRequired requirements; TRequired requirements;
std::string identifier;
BuildingID bid; //structure ID BuildingID bid; //structure ID
BuildingID upgrade; /// indicates that building "upgrade" can be improved by this, -1 = empty BuildingID upgrade; /// indicates that building "upgrade" can be improved by this, -1 = empty
@ -80,8 +78,13 @@ public:
CBuilding() : town(nullptr), mode(BUILD_NORMAL) {}; CBuilding() : town(nullptr), mode(BUILD_NORMAL) {};
const std::string &Name() const; std::string getJsonKey() const;
const std::string &Description() const;
std::string getNameTranslated() const;
std::string getDescriptionTranslated() const;
std::string getNameTextID() const;
std::string getDescriptionTextID() const;
//return base of upgrade(s) or this //return base of upgrade(s) or this
BuildingID getBase() const; BuildingID getBase() const;
@ -116,13 +119,12 @@ 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 & town; h & town;
h & bid; h & bid;
h & resources; h & resources;
h & produce; h & produce;
h & name;
h & description;
h & requirements; h & requirements;
h & upgrade; h & upgrade;
h & mode; h & mode;
@ -180,12 +182,15 @@ struct DLL_LINKAGE SPuzzleInfo
class DLL_LINKAGE CFaction : public Faction class DLL_LINKAGE CFaction : public Faction
{ {
public: friend class CTownHandler;
std::string name; //town name, by default - from TownName.txt std::string modScope; //town name, by default - from TownName.txt
std::string identifier; std::string identifier;
TFaction index; TFaction index;
const std::string & getName() const override;
public:
TerrainId nativeTerrain; TerrainId nativeTerrain;
EAlignment::EAlignment alignment; EAlignment::EAlignment alignment;
bool preferUndergroundPlacement; bool preferUndergroundPlacement;
@ -202,11 +207,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;
void registerIcons(const IconRegistar & cb) const override; void registerIcons(const IconRegistar & cb) const override;
FactionID getId() const override; FactionID getId() const override;
std::string getNameTranslated() const override;
std::string getNameTextID() const override;
bool hasTown() const override; bool hasTown() const override;
void updateFrom(const JsonNode & data); void updateFrom(const JsonNode & data);
@ -214,7 +221,7 @@ public:
template <typename Handler> void serialize(Handler &h, const int version) template <typename Handler> void serialize(Handler &h, const int version)
{ {
h & name; h & modScope;
h & identifier; h & identifier;
h & index; h & index;
h & nativeTerrain; h & nativeTerrain;
@ -228,11 +235,13 @@ public:
class DLL_LINKAGE CTown class DLL_LINKAGE CTown
{ {
friend class CTownHandler;
size_t namesCount;
public: public:
CTown(); CTown();
~CTown(); ~CTown();
std::string getLocalizedFactionName() const;
std::string getBuildingScope() const; std::string getBuildingScope() const;
std::set<si32> getAllBuildings() const; std::set<si32> getAllBuildings() const;
const CBuilding * getSpecialBuilding(BuildingSubID::EBuildingSubID subID) const; const CBuilding * getSpecialBuilding(BuildingSubID::EBuildingSubID subID) const;
@ -240,9 +249,11 @@ public:
void setGreeting(BuildingSubID::EBuildingSubID subID, const std::string message) const; //may affect only mutable field void setGreeting(BuildingSubID::EBuildingSubID subID, const std::string message) const; //may affect only mutable field
BuildingID::EBuildingID getBuildingType(BuildingSubID::EBuildingSubID subID) const; BuildingID::EBuildingID getBuildingType(BuildingSubID::EBuildingSubID subID) const;
CFaction * faction; std::string getRandomNameTranslated(size_t index) const;
std::string getRandomNameTextID(size_t index) const;
size_t getRandomNamesCount() const;
std::vector<std::string> names; //names of the town instances CFaction * faction;
/// level -> list of creatures on this tier /// level -> list of creatures on this tier
// TODO: replace with pointers to CCreature // TODO: replace with pointers to CCreature
@ -327,7 +338,7 @@ public:
template <typename Handler> void serialize(Handler &h, const int version) template <typename Handler> void serialize(Handler &h, const int version)
{ {
h & names; h & namesCount;
h & faction; h & faction;
h & creatures; h & creatures;
h & dwellings; h & dwellings;
@ -400,6 +411,7 @@ public:
static R getMappedValue(const JsonNode & node, const R defval, const std::map<std::string, R> & map, bool required = true); static R getMappedValue(const JsonNode & node, const R defval, const std::map<std::string, R> & map, bool required = true);
CTown * randomTown; CTown * randomTown;
CFaction * randomFaction;
CTownHandler(); CTownHandler();
~CTownHandler(); ~CTownHandler();

View File

@ -738,7 +738,7 @@ void CGTownInstance::onHeroLeave(const CGHeroInstance * h) const
std::string CGTownInstance::getObjectName() const std::string CGTownInstance::getObjectName() const
{ {
return name + ", " + town->faction->name; return name + ", " + town->faction->getNameTranslated();
} }
bool CGTownInstance::townEnvisagesBuilding(BuildingSubID::EBuildingSubID subId) const bool CGTownInstance::townEnvisagesBuilding(BuildingSubID::EBuildingSubID subId) const
@ -894,7 +894,7 @@ void CGTownInstance::initObj(CRandomGenerator & rand) ///initialize town structu
bool CGTownInstance::hasBuiltInOldWay(ETownType::ETownType type, BuildingID bid) const bool CGTownInstance::hasBuiltInOldWay(ETownType::ETownType type, BuildingID bid) const
{ {
return (this->town->faction != nullptr && this->town->faction->index == type && hasBuilt(bid)); return (this->town->faction != nullptr && this->town->faction->getIndex() == type && hasBuilt(bid));
} }
void CGTownInstance::newTurn(CRandomGenerator & rand) const void CGTownInstance::newTurn(CRandomGenerator & rand) const
@ -1178,7 +1178,7 @@ void CGTownInstance::updateAppearance()
std::string CGTownInstance::nodeName() const std::string CGTownInstance::nodeName() const
{ {
return "Town (" + (town ? town->faction->name : "unknown") + ") of " + name; return "Town (" + (town ? town->faction->getNameTranslated() : "unknown") + ") of " + name;
} }
void CGTownInstance::deserializationFix() void CGTownInstance::deserializationFix()
@ -1332,6 +1332,16 @@ CBonusSystemNode & CGTownInstance::whatShouldBeAttached()
return townAndVis; return townAndVis;
} }
std::string CGTownInstance::getNameTranslated() const
{
return name;
}
void CGTownInstance::setNameTranslated( const std::string & newName )
{
name = newName;
}
const CArmedInstance * CGTownInstance::getUpperArmy() const const CArmedInstance * CGTownInstance::getUpperArmy() const
{ {
if(garrisonHero) if(garrisonHero)
@ -1377,7 +1387,7 @@ bool CGTownInstance::hasBuilt(BuildingID buildingID) const
bool CGTownInstance::hasBuilt(BuildingID buildingID, int townID) const bool CGTownInstance::hasBuilt(BuildingID buildingID, int townID) const
{ {
if (townID == town->faction->index || townID == ETownType::ANY) if (townID == town->faction->getIndex() || townID == ETownType::ANY)
return hasBuilt(buildingID); return hasBuilt(buildingID);
return false; return false;
} }
@ -1513,7 +1523,7 @@ void CGTownInstance::serializeJsonOptions(JsonSerializeFormat & handler)
auto encodeBuilding = [this](si32 index) -> std::string auto encodeBuilding = [this](si32 index) -> std::string
{ {
return getTown()->buildings.at(BuildingID(index))->identifier; return getTown()->buildings.at(BuildingID(index))->getJsonKey();
}; };
const std::set<si32> standard = getTown()->getAllBuildings();//by default all buildings are allowed const std::set<si32> standard = getTown()->getAllBuildings();//by default all buildings are allowed
@ -1760,7 +1770,7 @@ void CTownBonus::onHeroVisit (const CGHeroInstance * h) const
case BuildingSubID::CUSTOM_VISITING_BONUS: case BuildingSubID::CUSTOM_VISITING_BONUS:
const auto building = town->town->buildings.at(bID); const auto building = town->town->buildings.at(bID);
if(!h->hasBonusFrom(Bonus::TOWN_STRUCTURE, Bonus::getSid32(building->town->faction->index, building->bid))) if(!h->hasBonusFrom(Bonus::TOWN_STRUCTURE, Bonus::getSid32(building->town->faction->getIndex(), building->bid)))
{ {
const auto & bonuses = building->onVisitBonuses; const auto & bonuses = building->onVisitBonuses;
applyBonuses(const_cast<CGHeroInstance *>(h), bonuses); applyBonuses(const_cast<CGHeroInstance *>(h), bonuses);
@ -1819,7 +1829,7 @@ GrowthInfo::Entry::Entry(const std::string &format, int _count)
GrowthInfo::Entry::Entry(int subID, BuildingID building, int _count) GrowthInfo::Entry::Entry(int subID, BuildingID building, int _count)
: count(_count) : count(_count)
{ {
description = boost::str(boost::format("%s %+d") % (*VLC->townh)[subID]->town->buildings.at(building)->Name() % count); description = boost::str(boost::format("%s %+d") % (*VLC->townh)[subID]->town->buildings.at(building)->getNameTranslated() % count);
} }
GrowthInfo::Entry::Entry(int _count, const std::string &fullDescription) GrowthInfo::Entry::Entry(int _count, const std::string &fullDescription)
@ -1870,12 +1880,12 @@ const std::string CGTownBuilding::getVisitingBonusGreeting() const
bonusGreeting = std::string(VLC->generaltexth->translate("vcmi.townHall.greetingDefence")); bonusGreeting = std::string(VLC->generaltexth->translate("vcmi.townHall.greetingDefence"));
break; break;
} }
auto buildingName = town->town->getSpecialBuilding(bType)->Name(); auto buildingName = town->town->getSpecialBuilding(bType)->getNameTranslated();
if(bonusGreeting.empty()) if(bonusGreeting.empty())
{ {
bonusGreeting = "Error: Bonus greeting for '%s' is not localized."; bonusGreeting = "Error: Bonus greeting for '%s' is not localized.";
logGlobal->error("'%s' building of '%s' faction has not localized bonus greeting.", buildingName, town->town->getLocalizedFactionName()); logGlobal->error("'%s' building of '%s' faction has not localized bonus greeting.", buildingName, town->town->faction->getNameTranslated());
} }
boost::algorithm::replace_first(bonusGreeting, "%s", buildingName); boost::algorithm::replace_first(bonusGreeting, "%s", buildingName);
town->town->setGreeting(bType, bonusGreeting); town->town->setGreeting(bType, bonusGreeting);
@ -1887,7 +1897,7 @@ const std::string CGTownBuilding::getCustomBonusGreeting(const Bonus & bonus) co
if(bonus.type == Bonus::TOWN_MAGIC_WELL) if(bonus.type == Bonus::TOWN_MAGIC_WELL)
{ {
auto bonusGreeting = std::string(VLC->generaltexth->translate("vcmi.townHall.greetingInTownMagicWell")); auto bonusGreeting = std::string(VLC->generaltexth->translate("vcmi.townHall.greetingInTownMagicWell"));
auto buildingName = town->town->getSpecialBuilding(bType)->Name(); auto buildingName = town->town->getSpecialBuilding(bType)->getNameTranslated();
boost::algorithm::replace_first(bonusGreeting, "%s", buildingName); boost::algorithm::replace_first(bonusGreeting, "%s", buildingName);
return bonusGreeting; return bonusGreeting;
} }

View File

@ -205,12 +205,12 @@ struct DLL_LINKAGE GrowthInfo
class DLL_LINKAGE CGTownInstance : public CGDwelling, public IShipyard, public IMarket class DLL_LINKAGE CGTownInstance : public CGDwelling, public IShipyard, public IMarket
{ {
std::string name; // name of town
public: public:
enum EFortLevel {NONE = 0, FORT = 1, CITADEL = 2, CASTLE = 3}; enum EFortLevel {NONE = 0, FORT = 1, CITADEL = 2, CASTLE = 3};
CTownAndVisitingHero townAndVis; CTownAndVisitingHero townAndVis;
const CTown * town; const CTown * town;
std::string name; // name of town
si32 builded; //how many buildings has been built this turn si32 builded; //how many buildings has been built this turn
si32 destroyed; //how many buildings has been destroyed this turn si32 destroyed; //how many buildings has been destroyed this turn
ConstTransitivePtr<CGHeroInstance> garrisonHero, visitingHero; ConstTransitivePtr<CGHeroInstance> garrisonHero, visitingHero;
@ -283,6 +283,9 @@ public:
void setGarrisonedHero(CGHeroInstance *h); void setGarrisonedHero(CGHeroInstance *h);
const CArmedInstance *getUpperArmy() const; //garrisoned hero if present or the town itself const CArmedInstance *getUpperArmy() const; //garrisoned hero if present or the town itself
std::string getNameTranslated() const;
void setNameTranslated( std::string const & newName );
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
bool passableFor(PlayerColor color) const override; bool passableFor(PlayerColor color) const override;

View File

@ -58,7 +58,7 @@ void CTownInstanceConstructor::afterLoadFinalization()
{ {
filters[entry.first] = LogicalExpression<BuildingID>(entry.second, [this](const JsonNode & node) filters[entry.first] = LogicalExpression<BuildingID>(entry.second, [this](const JsonNode & node)
{ {
return BuildingID(VLC->modh->identifiers.getIdentifier("building." + faction->identifier, node.Vector()[0]).get()); return BuildingID(VLC->modh->identifiers.getIdentifier("building." + faction->getJsonKey(), node.Vector()[0]).get());
}); });
} }
} }

View File

@ -565,7 +565,7 @@ void CMap::checkForObjectives()
{ {
const CGTownInstance *town = dynamic_cast<const CGTownInstance*>(cond.object); const CGTownInstance *town = dynamic_cast<const CGTownInstance*>(cond.object);
if (town) if (town)
boost::algorithm::replace_first(event.onFulfill, "%s", town->name); boost::algorithm::replace_first(event.onFulfill, "%s", town->getNameTranslated());
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->getNameTranslated()); boost::algorithm::replace_first(event.onFulfill, "%s", hero->getNameTranslated());

View File

@ -1942,7 +1942,7 @@ CGTownInstance * CMapLoaderH3M::readTown(int castleID)
bool hasName = reader.readBool(); bool hasName = reader.readBool();
if(hasName) if(hasName)
{ {
nt->name = reader.readString(); nt->setNameTranslated( reader.readString());
} }
bool hasGarrison = reader.readBool(); bool hasGarrison = reader.readBool();

View File

@ -388,11 +388,11 @@ void CMapFormatJson::serializeAllowedFactions(JsonSerializeFormat & handler, std
temp.resize(VLC->townh->size(), false); temp.resize(VLC->townh->size(), false);
auto standard = VLC->townh->getDefaultAllowed(); auto standard = VLC->townh->getDefaultAllowed();
if(handler.saving) if(handler.saving)
{ {
for(auto faction : VLC->townh->objects) for(auto faction : VLC->townh->objects)
if(faction->town && vstd::contains(value, faction->index)) if(faction->town && vstd::contains(value, faction->getIndex()))
temp[std::size_t(faction->index)] = true; temp[std::size_t(faction->getIndex())] = true;
} }
handler.serializeLIC("allowedFactions", &FactionID::decode, &FactionID::encode, standard, temp); handler.serializeLIC("allowedFactions", &FactionID::decode, &FactionID::encode, standard, temp);

View File

@ -175,7 +175,7 @@ std::string CMapGenerator::getMapDescription() const
if(pSettings.getStartingTown() != CMapGenOptions::CPlayerSettings::RANDOM_TOWN) if(pSettings.getStartingTown() != CMapGenOptions::CPlayerSettings::RANDOM_TOWN)
{ {
ss << ", " << GameConstants::PLAYER_COLOR_NAMES[pSettings.getColor().getNum()] ss << ", " << GameConstants::PLAYER_COLOR_NAMES[pSettings.getColor().getNum()]
<< " town choice is " << (*VLC->townh)[pSettings.getStartingTown()]->name; << " town choice is " << (*VLC->townh)[pSettings.getStartingTown()]->getNameTranslated();
} }
} }

View File

@ -264,7 +264,7 @@ void Inspector::updateProperties(CGTownInstance * o)
{ {
if(!o) return; if(!o) return;
addProperty("Town name", o->name, false); addProperty("Town name", o->getNameTranslated(), false);
auto * delegate = new TownBuildingsDelegate(*o); auto * delegate = new TownBuildingsDelegate(*o);
addProperty("Buildings", PropertyEditorPlaceholder(), delegate, false); addProperty("Buildings", PropertyEditorPlaceholder(), delegate, false);
@ -492,7 +492,7 @@ void Inspector::setProperty(CGTownInstance * o, const QString & key, const QVari
if(!o) return; if(!o) return;
if(key == "Town name") if(key == "Town name")
o->name = value.toString().toStdString(); o->setNameTranslated(value.toString().toStdString());
} }
void Inspector::setProperty(CGSignBottle * o, const QString & key, const QVariant & value) void Inspector::setProperty(CGSignBottle * o, const QString & key, const QVariant & value)

View File

@ -95,7 +95,7 @@ QStandardItem * TownBulidingsWidget::addBuilding(const CTown & ctown, int bId, s
return nullptr; return nullptr;
} }
QString name = tr(building->Name().c_str()); QString name = tr(building->getNameTranslated().c_str());
if(name.isEmpty()) if(name.isEmpty())
name = QString::fromStdString(defaultBuildingIdConversion(buildingId)); name = QString::fromStdString(defaultBuildingIdConversion(buildingId));

View File

@ -28,7 +28,7 @@ PlayerParams::PlayerParams(MapController & ctrl, int playerId, QWidget *parent)
for(auto idx : VLC->townh->getAllowedFactions()) for(auto idx : VLC->townh->getAllowedFactions())
{ {
CFaction * faction = VLC->townh->objects.at(idx); CFaction * faction = VLC->townh->objects.at(idx);
auto * item = new QListWidgetItem(QString::fromStdString(faction->name)); auto * item = new QListWidgetItem(QString::fromStdString(faction->getNameTranslated()));
item->setData(Qt::UserRole, QVariant::fromValue(idx)); item->setData(Qt::UserRole, QVariant::fromValue(idx));
item->setFlags(item->flags() | Qt::ItemIsUserCheckable); item->setFlags(item->flags() | Qt::ItemIsUserCheckable);
ui->allowedFactions->addItem(item); ui->allowedFactions->addItem(item);
@ -64,7 +64,7 @@ PlayerParams::PlayerParams(MapController & ctrl, int playerId, QWidget *parent)
{ {
if(playerInfo.hasMainTown && playerInfo.posOfMainTown == town->pos) if(playerInfo.hasMainTown && playerInfo.posOfMainTown == town->pos)
foundMainTown = townIndex; foundMainTown = townIndex;
const auto name = ctown->faction ? town->getObjectName() : town->name + ", (random)"; const auto name = ctown->faction ? town->getObjectName() : town->getNameTranslated() + ", (random)";
ui->mainTown->addItem(tr(name.c_str()), QVariant::fromValue(i)); ui->mainTown->addItem(tr(name.c_str()), QVariant::fromValue(i));
++townIndex; ++townIndex;
} }

View File

@ -1704,7 +1704,7 @@ void CGameHandler::setPortalDwelling(const CGTownInstance * town, bool forced=fa
const PlayerState * p = getPlayerState(town->tempOwner); const PlayerState * p = getPlayerState(town->tempOwner);
if (!p) if (!p)
{ {
logGlobal->warn("There is no player owner of town %s at %s", town->name, town->pos.toString()); logGlobal->warn("There is no player owner of town %s at %s", town->getNameTranslated(), town->pos.toString());
return; return;
} }
@ -2512,7 +2512,7 @@ bool CGameHandler::teleportHero(ObjectInstanceID hid, ObjectInstanceID dstid, ui
if (((h->getOwner() != t->getOwner()) if (((h->getOwner() != t->getOwner())
&& complain("Cannot teleport hero to another player")) && complain("Cannot teleport hero to another player"))
|| (from->town->faction->index != t->town->faction->index || (from->town->faction->getId() != t->town->faction->getId()
&& complain("Source town and destination town should belong to the same faction")) && complain("Source town and destination town should belong to the same faction"))
|| ((!from || !from->hasBuilt(BuildingSubID::CASTLE_GATE)) || ((!from || !from->hasBuilt(BuildingSubID::CASTLE_GATE))
@ -3437,9 +3437,9 @@ bool CGameHandler::buildStructure(ObjectInstanceID tid, BuildingID requestedID,
if(!t) if(!t)
COMPLAIN_RETF("No such town (ID=%s)!", tid); COMPLAIN_RETF("No such town (ID=%s)!", tid);
if(!t->town->buildings.count(requestedID)) if(!t->town->buildings.count(requestedID))
COMPLAIN_RETF("Town of faction %s does not have info about building ID=%s!", t->town->faction->name % requestedID); COMPLAIN_RETF("Town of faction %s does not have info about building ID=%s!", t->town->faction->getNameTranslated() % requestedID);
if(t->hasBuilt(requestedID)) if(t->hasBuilt(requestedID))
COMPLAIN_RETF("Building %s is already built in %s", t->town->buildings.at(requestedID)->Name() % t->name); COMPLAIN_RETF("Building %s is already built in %s", t->town->buildings.at(requestedID)->getNameTranslated() % t->getNameTranslated());
const CBuilding * requestedBuilding = t->town->buildings.at(requestedID); const CBuilding * requestedBuilding = t->town->buildings.at(requestedID);
@ -7066,7 +7066,7 @@ void CGameHandler::handleCheatCode(std::string & cheat, PlayerColor player, cons
for (auto & build : town->town->buildings) for (auto & build : town->town->buildings)
{ {
if (!town->hasBuilt(build.first) if (!town->hasBuilt(build.first)
&& !build.second->Name().empty() && !build.second->getNameTranslated().empty()
&& build.first != BuildingID::SHIP) && build.first != BuildingID::SHIP)
{ {
buildStructure(town->id, build.first, true); buildStructure(town->id, build.first, true);