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)
{
auto name = t->town->buildings.at(building)->Name();
logAi->debug("Player %d will build %s in town of %s at %s", ai->playerID, name, t->name, t->pos.toString());
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->getNameTranslated(), t->pos.toString());
cb->buildBuilding(t, building); //just do this;
}

View File

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

View File

@ -50,14 +50,14 @@ Goals::TGoalVec DefenceBehavior::decompose() 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 treats = { treatNode.fastestDanger, treatNode.maximumDanger };
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;
}
@ -79,7 +79,7 @@ void DefenceBehavior::evaluateDefence(Goals::TGoalVec & tasks, const CGTownInsta
logAi->trace(
"Hero %s in garrison of town %s is suposed to defend the town",
town->garrisonHero->getNameTranslated(),
town->name);
town->getNameTranslated());
return;
}
@ -88,7 +88,7 @@ void DefenceBehavior::evaluateDefence(Goals::TGoalVec & tasks, const CGTownInsta
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)));
}
@ -98,7 +98,7 @@ void DefenceBehavior::evaluateDefence(Goals::TGoalVec & tasks, const CGTownInsta
{
logAi->trace(
"Town %s has treat %lld in %s turns, hero: %s",
town->name,
town->getNameTranslated(),
treat.danger,
std::to_string(treat.turn),
treat.hero->getNameTranslated());
@ -187,7 +187,7 @@ void DefenceBehavior::evaluateDefence(Goals::TGoalVec & tasks, const CGTownInsta
if(paths.empty())
{
logAi->trace("No ways to defend town %s", town->name);
logAi->trace("No ways to defend town %s", town->getNameTranslated());
continue;
}

View File

@ -46,7 +46,7 @@ bool BuildThis::operator==(const BuildThis & other) 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)
@ -58,7 +58,7 @@ void BuildThis::accept(AIGateway * ai)
if(cb->canBuildStructure(town, b) == EBuildingState::ALLOWED)
{
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);
return;

View File

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

View File

@ -33,7 +33,7 @@ ExchangeSwapTownHeroes::ExchangeSwapTownHeroes(
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
@ -60,7 +60,7 @@ void ExchangeSwapTownHeroes::accept(AIGateway * ai)
ai->buildArmyIn(town);
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;
}
@ -91,7 +91,7 @@ void ExchangeSwapTownHeroes::accept(AIGateway * ai)
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
{
return "Recruit hero at " + town->name;
return "Recruit hero at " + town->getNameTranslated();
}
void RecruitHero::accept(AIGateway * ai)
@ -40,7 +40,7 @@ void RecruitHero::accept(AIGateway * ai)
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);

View File

@ -34,7 +34,7 @@ void TownPortalAction::execute(const CGHeroInstance * hero) 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

View File

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

View File

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

View File

@ -65,7 +65,7 @@ std::string BattleSiegeController::getWallPieceImageName(EWallVisual::EWallVisua
{
case EWallVisual::BACKGROUND_WALL:
{
switch(town->town->faction->index)
switch(town->town->faction->getIndex())
{
case ETownType::RAMPART:
case ETownType::NECROPOLIS:
@ -135,8 +135,8 @@ bool BattleSiegeController::getWallPieceExistance(EWallVisual::EWallVisual what)
switch (what)
{
case EWallVisual::MOAT: return town->hasBuilt(BuildingID::CITADEL) && town->town->faction->index != 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: return town->hasBuilt(BuildingID::CITADEL) && town->town->faction->getIndex() != ETownType::TOWER;
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::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;

View File

@ -203,7 +203,7 @@ void CBonusSelection::createBonusesIcons()
picNumber = -1;
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;
}

View File

@ -184,7 +184,7 @@ std::string OptionsTab::CPlayerSettingsHelper::getName()
default:
{
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 morale: return CGI->generaltexth->heroscrn[ 4 - (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 flag: return "";
}
@ -228,10 +228,10 @@ std::string CComponent::getSubtitleInternal()
auto building = (*CGI->townh)[subtype]->town->buildings[BuildingID(val)];
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 building->Name();
return building->getNameTranslated();
}
case hero: return "";
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);
if (bid < BuildingID::DWELL_FIRST)
{
CRClickPopup::createAndPush(CInfoWindow::genText(bld->Name(), bld->Description()),
std::make_shared<CComponent>(CComponent::building, bld->town->faction->index, bld->bid));
CRClickPopup::createAndPush(CInfoWindow::genText(bld->getNameTranslated(), bld->getDescriptionTranslated()),
std::make_shared<CComponent>(CComponent::building, bld->town->faction->getIndex(), bld->bid));
}
else
{
@ -235,7 +235,7 @@ std::string CBuildingRect::getSubtitle()//hover text for building
int bid = getBuilding()->bid;
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%
{
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)
GH.pushIntT<CMarketplaceWindow>(town, town->visitingHero, EMarketMode::RESOURCE_ARTIFACT);
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;
case BuildingSubID::FOUNTAIN_OF_FORTUNE:
@ -747,7 +747,7 @@ void CCastleBuildings::buildingClicked(BuildingID building, BuildingSubID::EBuil
if(getHero())
GH.pushIntT<CMarketplaceWindow>(town, getHero(), EMarketMode::CREATURE_RESOURCE);
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;
case BuildingSubID::MAGIC_UNIVERSITY:
@ -801,7 +801,7 @@ void CCastleBuildings::enterBlacksmith(ArtifactID artifactID)
const CGHeroInstance *hero = town->visitingHero;
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;
}
auto art = artifactID.toArtifact(CGI->artifacts());
@ -815,7 +815,7 @@ void CCastleBuildings::enterBlacksmith(ArtifactID artifactID)
void CCastleBuildings::enterBuilding(BuildingID 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()
@ -831,7 +831,7 @@ void CCastleBuildings::enterCastleGate()
{
const CGTownInstance *t = Town;
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
{
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)
{
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 hasProduced;
if(this->town->town->faction->index == (TFaction)ETownType::RAMPART)
if(this->town->town->faction->getIndex() == (TFaction)ETownType::RAMPART)
{
hasNotProduced = CGI->generaltexth->allTexts[677];
hasProduced = CGI->generaltexth->allTexts[678];
}
else
{
auto buildingName = town->town->getSpecialBuilding(subID)->Name();
auto buildingName = town->town->getSpecialBuilding(subID)->getNameTranslated();
hasNotProduced = std::string(CGI->generaltexth->translate("vcmi.townHall.hasNotProduced"));
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);
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
{
@ -1114,7 +1114,7 @@ void CTownInfo::hover(bool on)
if(on)
{
if(building )
GH.statusbar->write(building->Name());
GH.statusbar->write(building->getNameTranslated());
}
else
{
@ -1126,8 +1126,8 @@ void CTownInfo::clickRight(tribool down, bool previousState)
{
if(building && down)
{
auto c = std::make_shared<CComponent>(CComponent::building, building->town->faction->index, building->bid);
CRClickPopup::createAndPush(CInfoWindow::genText(building->Name(), building->Description()), c);
auto c = std::make_shared<CComponent>(CComponent::building, building->town->faction->getIndex(), building->bid);
CRClickPopup::createAndPush(CInfoWindow::genText(building->getNameTranslated(), building->getDescriptionTranslated()), c);
}
}
@ -1152,7 +1152,7 @@ CCastleInterface::CCastleInterface(const CGTownInstance * Town, const CGTownInst
garr->type |= REDRAW_PARENT;
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);
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);
if(iconIndex[state] >=0)
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
if(state >= EBuildingState::BUILDING_ERROR)
@ -1334,7 +1334,7 @@ void CHallInterface::CBuildingBox::hover(bool on)
toPrint = CGI->generaltexth->allTexts[223];
else
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);
}
else
@ -1368,7 +1368,7 @@ CHallInterface::CHallInterface(const CGTownInstance * Town):
auto statusbarBackground = std::make_shared<CPicture>(background->getSurface(), barRect, 5, 556, false);
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->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);
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()));
description = std::make_shared<CTextBox>(building->Description(), Rect(33, 135, 329, 67), 0, FONT_MEDIUM, ETextAlignment::CENTER);
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->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);
//Create components for all required resources
@ -1432,8 +1432,8 @@ CBuildWindow::CBuildWindow(const CGTownInstance *Town, const CBuilding * Buildin
if(!rightClick)
{ //normal window
std::string tooltipYes = boost::str(boost::format(CGI->generaltexth->allTexts[595]) % building->Name());
std::string tooltipNo = boost::str(boost::format(CGI->generaltexth->allTexts[596]) % 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->getNameTranslated());
buy = std::make_shared<CButton>(Point(45, 446), "IBUY30", CButton::tooltip(tooltipYes), [&](){ buyFunc(); }, SDLK_RETURN);
buy->setBorderColor(Colors::METALLIC_GOLD);
@ -1460,7 +1460,7 @@ std::string CBuildWindow::getTextForState(int state)
case EBuildingState::ALREADY_PRESENT:
case EBuildingState::CANT_BUILD_TODAY:
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;
case EBuildingState::ALLOWED:
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
{
return town->town->buildings.at(build)->Name();
return town->town->buildings.at(build)->getNameTranslated();
};
ret = CGI->generaltexth->allTexts[52];
@ -1478,7 +1478,7 @@ std::string CBuildWindow::getTextForState(int state)
case EBuildingState::MISSING_BASE:
{
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;
}
}
@ -1542,9 +1542,9 @@ CFortScreen::CFortScreen(const CGTownInstance * town):
fortSize--;
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->assignedKeys.insert(SDLK_ESCAPE);
@ -1629,7 +1629,7 @@ CFortScreen::RecruitArea::RecruitArea(int posX, int posY, const CGTownInstance *
if(getMyBuilding() != nullptr)
{
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))
{

View File

@ -767,7 +767,7 @@ CTownItem::CTownItem(const CGTownInstance * Town)
{
OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE);
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]));
hall = std::make_shared<CTownInfo>( 69, 31, town, true);

View File

@ -668,14 +668,14 @@ CMarketplaceWindow::CMarketplaceWindow(const IMarket * Market, const CGHeroInsta
switch (mode)
{
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;
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;
break;
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
// 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)
{
auto faction = town->town->faction->index;
auto faction = town->town->faction->getId();
auto bid = town->town->getSpecialBuilding(BuildingSubID::MAGIC_UNIVERSITY)->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>
{
using EntityT<FactionID>::getName;
public:
virtual bool hasTown() const = 0;
virtual std::string getNameTranslated() const = 0;
virtual std::string getNameTextID() const = 0;
};
VCMI_LIB_NAMESPACE_END

View File

@ -328,7 +328,7 @@ CGHeroInstance * CGameState::HeroesPool::pickHeroFor(bool native, PlayerColor pl
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;
}
@ -339,7 +339,7 @@ CGHeroInstance * CGameState::HeroesPool::pickHeroFor(bool native, PlayerColor pl
for(auto & elem : available)
{
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
}
@ -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
{
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)
@ -376,7 +376,7 @@ CGHeroInstance * CGameState::HeroesPool::pickHeroFor(bool native, PlayerColor pl
r = rand.nextInt(sum - 1);
for (auto & elem : pool)
{
r -= elem->type->heroClass->selectionProbability[town->faction->index];
r -= elem->type->heroClass->selectionProbability[town->faction->getIndex()];
if(r < 0)
{
ret = elem;
@ -623,7 +623,7 @@ std::pair<Obj,int> CGameState::pickObject (CGObjectInstance *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()));
}
@ -1711,9 +1711,10 @@ void CGameState::initTowns()
{
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
@ -3076,7 +3077,7 @@ void InfoAboutTown::initFromTown(const CGTownInstance *t, bool detailed)
army = ArmyDescriptor(t->getUpperArmy(), detailed);
built = t->builded;
fortLevel = t->fortLevel();
name = t->name;
name = t->getNameTranslated();
tType = t->town;
vstd::clear_pointer(details);

View File

@ -364,11 +364,11 @@ void CHeroClassHandler::afterLoadFinalization()
{
if (!faction->town)
continue;
if (heroClass->selectionProbability.count(faction->index))
if (heroClass->selectionProbability.count(faction->getIndex()))
continue;
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
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 }
};
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
@ -109,7 +124,7 @@ int32_t CFaction::getIconIndex() const
const std::string & CFaction::getName() const
{
return name;
return identifier;
}
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
{
return FactionID(index);
@ -173,12 +198,19 @@ CTown::~CTown()
str.dellNull();
}
std::string CTown::getLocalizedFactionName() const
std::string CTown::getRandomNameTranslated(size_t index) const
{
if(faction == nullptr)
return "Random";
else
return faction->name;
return VLC->generaltexth->translate(getRandomNameTextID(index));
}
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
@ -187,7 +219,7 @@ std::string CTown::getBuildingScope() const
//no faction == random faction
return "building";
else
return "building." + faction->identifier;
return "building." + faction->getJsonKey();
}
std::set<si32> CTown::getAllBuildings() const
@ -231,6 +263,11 @@ void CTown::setGreeting(BuildingSubID::EBuildingSubID subID, const std::string m
CTownHandler::CTownHandler()
{
randomTown = new CTown();
randomFaction = new CFaction();
randomFaction->town = randomTown;
randomTown->faction = randomFaction;
randomFaction->identifier = "random";
randomFaction->modScope = "core";
}
CTownHandler::~CTownHandler()
@ -460,10 +497,10 @@ void CTownHandler::addBonusesForVanilaBuilding(CBuilding * building)
}
else if(building->bid == BuildingID::GRAIL
&& 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 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->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::ostringstream descr;
descr << build->name;
descr << build->getNameTranslated();
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())
{
auto bonus = JsonUtils::parseBuildingBonus(b, building->bid, building->name);
auto bonus = JsonUtils::parseBuildingBonus(b, building->bid, building->getNameTranslated());
if(bonus == nullptr)
continue;
@ -533,7 +570,7 @@ void CTownHandler::loadSpecialBuildingBonuses(const JsonNode & source, BonusList
auto limPtr = dynamic_cast<CreatureFactionLimiter*>(bonus->limiter.get());
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.
if(bonus->propagator != nullptr
@ -567,8 +604,10 @@ void CTownHandler::loadBuilding(CTown * town, const std::string & stringID, cons
ret->identifier = stringID;
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->produce = TResources(source["produce"]);
@ -589,7 +628,7 @@ void CTownHandler::loadBuilding(CTown * town, const std::string & stringID, cons
ret->subId = BuildingSubID::CUSTOM_VISITING_BONUS;
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
@ -630,7 +669,7 @@ void CTownHandler::loadBuilding(CTown * town, const std::string & stringID, cons
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.") %
stringID % ret->town->getLocalizedFactionName()));
stringID % ret->town->faction->getNameTranslated()));
}
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->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)];
});
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)];
});
}
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)];
});
@ -729,7 +768,7 @@ void CTownHandler::loadTownHall(CTown &town, const JsonNode & source)
auto & dst = dstBox[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);
});
@ -757,7 +796,7 @@ void CTownHandler::loadSiegeScreen(CTown &town, const JsonNode & source)
auto crId = CreatureID(creature);
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!"
, town.faction->name
, town.faction->getNameTranslated()
, (*VLC->creh)[crId]->getNameSingularTranslated());
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->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
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->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->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();
faction->index = static_cast<TFaction>(index);
faction->name = source["name"].String();
faction->modScope = scope;
faction->identifier = identifier;
VLC->generaltexth->registerString(faction->getNameTextID(), source["name"].String());
faction->creatureBg120 = source["creatureBackground"]["120px"].String();
faction->creatureBg130 = source["creatureBackground"]["130px"].String();

View File

@ -38,9 +38,8 @@ class JsonSerializeFormat;
class DLL_LINKAGE CBuilding
{
std::string name;
std::string description;
std::string modScope;
std::string identifier;
public:
typedef LogicalExpression<BuildingID> TRequired;
@ -49,7 +48,6 @@ public:
TResources resources;
TResources produce;
TRequired requirements;
std::string identifier;
BuildingID bid; //structure ID
BuildingID upgrade; /// indicates that building "upgrade" can be improved by this, -1 = empty
@ -80,8 +78,13 @@ public:
CBuilding() : town(nullptr), mode(BUILD_NORMAL) {};
const std::string &Name() const;
const std::string &Description() const;
std::string getJsonKey() const;
std::string getNameTranslated() const;
std::string getDescriptionTranslated() const;
std::string getNameTextID() const;
std::string getDescriptionTextID() const;
//return base of upgrade(s) or this
BuildingID getBase() const;
@ -116,13 +119,12 @@ public:
template <typename Handler> void serialize(Handler &h, const int version)
{
h & modScope;
h & identifier;
h & town;
h & bid;
h & resources;
h & produce;
h & name;
h & description;
h & requirements;
h & upgrade;
h & mode;
@ -180,12 +182,15 @@ struct DLL_LINKAGE SPuzzleInfo
class DLL_LINKAGE CFaction : public Faction
{
public:
std::string name; //town name, by default - from TownName.txt
friend class CTownHandler;
std::string modScope; //town name, by default - from TownName.txt
std::string identifier;
TFaction index;
const std::string & getName() const override;
public:
TerrainId nativeTerrain;
EAlignment::EAlignment alignment;
bool preferUndergroundPlacement;
@ -202,11 +207,13 @@ public:
int32_t getIndex() const override;
int32_t getIconIndex() const override;
const std::string & getName() const override;
const std::string & getJsonKey() const override;
void registerIcons(const IconRegistar & cb) const override;
FactionID getId() const override;
std::string getNameTranslated() const override;
std::string getNameTextID() const override;
bool hasTown() const override;
void updateFrom(const JsonNode & data);
@ -214,7 +221,7 @@ public:
template <typename Handler> void serialize(Handler &h, const int version)
{
h & name;
h & modScope;
h & identifier;
h & index;
h & nativeTerrain;
@ -228,11 +235,13 @@ public:
class DLL_LINKAGE CTown
{
friend class CTownHandler;
size_t namesCount;
public:
CTown();
~CTown();
std::string getLocalizedFactionName() const;
std::string getBuildingScope() const;
std::set<si32> getAllBuildings() 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
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
// TODO: replace with pointers to CCreature
@ -327,7 +338,7 @@ public:
template <typename Handler> void serialize(Handler &h, const int version)
{
h & names;
h & namesCount;
h & faction;
h & creatures;
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);
CTown * randomTown;
CFaction * randomFaction;
CTownHandler();
~CTownHandler();

View File

@ -738,7 +738,7 @@ void CGTownInstance::onHeroLeave(const CGHeroInstance * h) const
std::string CGTownInstance::getObjectName() const
{
return name + ", " + town->faction->name;
return name + ", " + town->faction->getNameTranslated();
}
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
{
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
@ -1178,7 +1178,7 @@ void CGTownInstance::updateAppearance()
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()
@ -1332,6 +1332,16 @@ CBonusSystemNode & CGTownInstance::whatShouldBeAttached()
return townAndVis;
}
std::string CGTownInstance::getNameTranslated() const
{
return name;
}
void CGTownInstance::setNameTranslated( const std::string & newName )
{
name = newName;
}
const CArmedInstance * CGTownInstance::getUpperArmy() const
{
if(garrisonHero)
@ -1377,7 +1387,7 @@ bool CGTownInstance::hasBuilt(BuildingID buildingID) 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 false;
}
@ -1513,7 +1523,7 @@ void CGTownInstance::serializeJsonOptions(JsonSerializeFormat & handler)
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
@ -1760,7 +1770,7 @@ void CTownBonus::onHeroVisit (const CGHeroInstance * h) const
case BuildingSubID::CUSTOM_VISITING_BONUS:
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;
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)
: 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)
@ -1870,12 +1880,12 @@ const std::string CGTownBuilding::getVisitingBonusGreeting() const
bonusGreeting = std::string(VLC->generaltexth->translate("vcmi.townHall.greetingDefence"));
break;
}
auto buildingName = town->town->getSpecialBuilding(bType)->Name();
auto buildingName = town->town->getSpecialBuilding(bType)->getNameTranslated();
if(bonusGreeting.empty())
{
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);
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)
{
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);
return bonusGreeting;
}

View File

@ -205,12 +205,12 @@ struct DLL_LINKAGE GrowthInfo
class DLL_LINKAGE CGTownInstance : public CGDwelling, public IShipyard, public IMarket
{
std::string name; // name of town
public:
enum EFortLevel {NONE = 0, FORT = 1, CITADEL = 2, CASTLE = 3};
CTownAndVisitingHero townAndVis;
const CTown * town;
std::string name; // name of town
si32 builded; //how many buildings has been built this turn
si32 destroyed; //how many buildings has been destroyed this turn
ConstTransitivePtr<CGHeroInstance> garrisonHero, visitingHero;
@ -283,6 +283,9 @@ public:
void setGarrisonedHero(CGHeroInstance *h);
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;

View File

@ -58,7 +58,7 @@ void CTownInstanceConstructor::afterLoadFinalization()
{
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);
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);
if (hero)
boost::algorithm::replace_first(event.onFulfill, "%s", hero->getNameTranslated());

View File

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

View File

@ -391,8 +391,8 @@ void CMapFormatJson::serializeAllowedFactions(JsonSerializeFormat & handler, std
if(handler.saving)
{
for(auto faction : VLC->townh->objects)
if(faction->town && vstd::contains(value, faction->index))
temp[std::size_t(faction->index)] = true;
if(faction->town && vstd::contains(value, faction->getIndex()))
temp[std::size_t(faction->getIndex())] = true;
}
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)
{
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;
addProperty("Town name", o->name, false);
addProperty("Town name", o->getNameTranslated(), false);
auto * delegate = new TownBuildingsDelegate(*o);
addProperty("Buildings", PropertyEditorPlaceholder(), delegate, false);
@ -492,7 +492,7 @@ void Inspector::setProperty(CGTownInstance * o, const QString & key, const QVari
if(!o) return;
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)

View File

@ -95,7 +95,7 @@ QStandardItem * TownBulidingsWidget::addBuilding(const CTown & ctown, int bId, s
return nullptr;
}
QString name = tr(building->Name().c_str());
QString name = tr(building->getNameTranslated().c_str());
if(name.isEmpty())
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())
{
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->setFlags(item->flags() | Qt::ItemIsUserCheckable);
ui->allowedFactions->addItem(item);
@ -64,7 +64,7 @@ PlayerParams::PlayerParams(MapController & ctrl, int playerId, QWidget *parent)
{
if(playerInfo.hasMainTown && playerInfo.posOfMainTown == town->pos)
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));
++townIndex;
}

View File

@ -1704,7 +1704,7 @@ void CGameHandler::setPortalDwelling(const CGTownInstance * town, bool forced=fa
const PlayerState * p = getPlayerState(town->tempOwner);
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;
}
@ -2512,7 +2512,7 @@ bool CGameHandler::teleportHero(ObjectInstanceID hid, ObjectInstanceID dstid, ui
if (((h->getOwner() != t->getOwner())
&& 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"))
|| ((!from || !from->hasBuilt(BuildingSubID::CASTLE_GATE))
@ -3437,9 +3437,9 @@ bool CGameHandler::buildStructure(ObjectInstanceID tid, BuildingID requestedID,
if(!t)
COMPLAIN_RETF("No such town (ID=%s)!", tid);
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))
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);
@ -7066,7 +7066,7 @@ void CGameHandler::handleCheatCode(std::string & cheat, PlayerColor player, cons
for (auto & build : town->town->buildings)
{
if (!town->hasBuilt(build.first)
&& !build.second->Name().empty()
&& !build.second->getNameTranslated().empty()
&& build.first != BuildingID::SHIP)
{
buildStructure(town->id, build.first, true);