1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-12-12 10:03:53 +02:00

Merge pull request #4731 from IvanSavenko/reduce_pointers

Reduce usage of pointers to VLC entities
This commit is contained in:
Ivan Savenko 2024-10-10 15:29:40 +03:00 committed by GitHub
commit 22ac88ecc4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
83 changed files with 445 additions and 468 deletions

View File

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

View File

@ -144,7 +144,7 @@ std::vector<SlotInfo> ArmyManager::getBestArmy(const IBonusBearer * armyCarrier,
for(auto & slot : sortedSlots)
{
alignmentMap[slot.creature->getFaction()] += slot.power;
alignmentMap[slot.creature->getFactionID()] += slot.power;
}
std::set<FactionID> allowedFactions;
@ -178,7 +178,7 @@ std::vector<SlotInfo> ArmyManager::getBestArmy(const IBonusBearer * armyCarrier,
for(auto & slot : sortedSlots)
{
if(vstd::contains(allowedFactions, slot.creature->getFaction()))
if(vstd::contains(allowedFactions, slot.creature->getFactionID()))
{
auto slotID = newArmyInstance.getSlotFor(slot.creature->getId());

View File

@ -17,7 +17,7 @@ namespace NKAI
void BuildAnalyzer::updateTownDwellings(TownDevelopmentInfo & developmentInfo)
{
auto townInfo = developmentInfo.town->town;
auto townInfo = developmentInfo.town->getTown();
auto creatures = townInfo->creatures;
auto buildings = townInfo->getAllBuildings();
@ -31,7 +31,7 @@ void BuildAnalyzer::updateTownDwellings(TownDevelopmentInfo & developmentInfo)
}
}
for(int level = 0; level < developmentInfo.town->town->creatures.size(); level++)
for(int level = 0; level < developmentInfo.town->getTown()->creatures.size(); level++)
{
logAi->trace("Checking dwelling level %d", level);
BuildingInfo nextToBuild = BuildingInfo();
@ -82,7 +82,7 @@ void BuildAnalyzer::updateOtherBuildings(TownDevelopmentInfo & developmentInfo)
{
for(auto & buildingID : buildingSet)
{
if(!developmentInfo.town->hasBuilt(buildingID) && developmentInfo.town->town->buildings.count(buildingID))
if(!developmentInfo.town->hasBuilt(buildingID) && developmentInfo.town->getTown()->buildings.count(buildingID))
{
developmentInfo.addBuildingToBuild(getBuildingOrPrerequisite(developmentInfo.town, buildingID));
@ -198,7 +198,7 @@ BuildingInfo BuildAnalyzer::getBuildingOrPrerequisite(
bool excludeDwellingDependencies) const
{
BuildingID building = toBuild;
auto townInfo = town->town;
auto townInfo = town->getTown();
const CBuilding * buildPtr = townInfo->buildings.at(building);
const CCreature * creature = nullptr;
@ -327,7 +327,7 @@ bool BuildAnalyzer::hasAnyBuilding(int32_t alignment, BuildingID bid) const
{
for(auto tdi : developmentInfos)
{
if(tdi.town->getFaction() == alignment && tdi.town->hasBuilt(bid))
if(tdi.town->getFactionID() == alignment && tdi.town->hasBuilt(bid))
return true;
}

View File

@ -71,7 +71,7 @@ float HeroManager::evaluateSecSkill(SecondarySkill skill, const CGHeroInstance *
float HeroManager::evaluateSpeciality(const CGHeroInstance * hero) const
{
auto heroSpecial = Selector::source(BonusSource::HERO_SPECIAL, BonusSourceID(hero->type->getId()));
auto heroSpecial = Selector::source(BonusSource::HERO_SPECIAL, BonusSourceID(hero->getHeroTypeID()));
auto secondarySkillBonus = Selector::targetSourceType()(BonusSource::SECONDARY_SKILL);
auto specialSecondarySkillBonuses = hero->getBonuses(heroSpecial.And(secondarySkillBonus));
auto secondarySkillBonuses = hero->getBonuses(Selector::sourceTypeSel(BonusSource::SECONDARY_SKILL));

View File

@ -1120,7 +1120,7 @@ public:
uint64_t RewardEvaluator::getUpgradeArmyReward(const CGTownInstance * town, const BuildingInfo & bi) const
{
if(ai->buildAnalyzer->hasAnyBuilding(town->getFaction(), bi.id))
if(ai->buildAnalyzer->hasAnyBuilding(town->getFactionID(), bi.id))
return 0;
auto creaturesToUpgrade = ai->armyManager->getTotalCreaturesAvailable(bi.baseCreatureID);

View File

@ -23,7 +23,7 @@ BuildThis::BuildThis(BuildingID Bid, const CGTownInstance * tid)
: ElementarGoal(Goals::BUILD_STRUCTURE)
{
buildingInfo = BuildingInfo(
tid->town->buildings.at(Bid),
tid->getTown()->buildings.at(Bid),
nullptr,
CreatureID::NONE,
tid,
@ -52,7 +52,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)->getNameTranslated(), town->getNameTranslated(), town->anchorPos().toString());
ai->playerID, town->getTown()->buildings.at(b)->getNameTranslated(), town->getNameTranslated(), town->anchorPos().toString());
cb->buildBuilding(town, b);
return;

View File

@ -23,13 +23,13 @@ bool BuildingManager::tryBuildThisStructure(const CGTownInstance * t, BuildingID
return false;
}
if (!vstd::contains(t->town->buildings, building))
if (!vstd::contains(t->getTown()->buildings, building))
return false; // no such building in town
if (t->hasBuilt(building)) //Already built? Shouldn't happen in general
return true;
const CBuilding * buildPtr = t->town->buildings.at(building);
const CBuilding * buildPtr = t->getTown()->buildings.at(building);
auto toBuild = buildPtr->requirements.getFulfillmentCandidates([&](const BuildingID & buildID)
{
@ -51,7 +51,7 @@ bool BuildingManager::tryBuildThisStructure(const CGTownInstance * t, BuildingID
for (const auto & buildID : toBuild)
{
const CBuilding * b = t->town->buildings.at(buildID);
const CBuilding * b = t->getTown()->buildings.at(buildID);
EBuildingState canBuild = cb->canBuildStructure(t, buildID);
if (canBuild == EBuildingState::ALLOWED)
@ -220,7 +220,7 @@ bool BuildingManager::getBuildingOptions(const CGTownInstance * t)
//at the end, try to get and build any extra buildings with nonstandard slots (for example HotA 3rd level dwelling)
std::vector<BuildingID> extraBuildings;
for (auto buildingInfo : t->town->buildings)
for (auto buildingInfo : t->getTown()->buildings)
{
if (buildingInfo.first > BuildingID::DWELL_UP2_FIRST)
extraBuildings.push_back(buildingInfo.first);

View File

@ -56,7 +56,7 @@ TSubgoal BuildThis::whatToDoToAchieve()
case EBuildingState::ALLOWED:
case EBuildingState::NO_RESOURCES:
{
auto res = town->town->buildings.at(BuildingID(bid))->resources;
auto res = town->getTown()->buildings.at(BuildingID(bid))->resources;
return ai->ah->whatToDo(res, iAmElementar()); //realize immediately or gather resources
}
break;

View File

@ -88,13 +88,13 @@ TGoalVec GatherTroops::getAllPossibleSubgoals()
}
auto creature = VLC->creatures()->getByIndex(objid);
if(t->getFaction() == creature->getFaction()) //TODO: how to force AI to build unupgraded creatures? :O
if(t->getFactionID() == creature->getFactionID()) //TODO: how to force AI to build unupgraded creatures? :O
{
auto tryFindCreature = [&]() -> std::optional<std::vector<CreatureID>>
{
if(vstd::isValidIndex(t->town->creatures, creature->getLevel() - 1))
if(vstd::isValidIndex(t->getTown()->creatures, creature->getLevel() - 1))
{
auto itr = t->town->creatures.begin();
auto itr = t->getTown()->creatures.begin();
std::advance(itr, creature->getLevel() - 1);
return make_optional(*itr);
}
@ -109,7 +109,7 @@ TGoalVec GatherTroops::getAllPossibleSubgoals()
if(upgradeNumber < 0)
continue;
BuildingID bid(BuildingID::DWELL_FIRST + creature->getLevel() - 1 + upgradeNumber * t->town->creatures.size());
BuildingID bid(BuildingID::DWELL_FIRST + creature->getLevel() - 1 + upgradeNumber * t->getTown()->creatures.size());
if(t->hasBuilt(bid) && ai->ah->freeResources().canAfford(creature->getFullRecruitCost())) //this assumes only creatures with dwellings are assigned to faction
{
solutions.push_back(sptr(BuyArmy(t, creature->getAIValue() * this->value).setobjid(objid)));

View File

@ -69,7 +69,7 @@ std::optional<int> MapObjectsEvaluator::getObjectValue(const CGObjectInstance *
{
//special case handling: in-game heroes have hero ID as object subID, but when reading configs available hero object subID's are hero classes
auto hero = dynamic_cast<const CGHeroInstance*>(obj);
return getObjectValue(obj->ID, hero->type->heroClass->getIndex());
return getObjectValue(obj->ID, hero->getHeroClassID());
}
else if(obj->ID == Obj::PRISON)
{

View File

@ -1994,7 +1994,7 @@ bool VCAI::moveHeroToTile(int3 dst, HeroPtr h)
void VCAI::buildStructure(const CGTownInstance * t, BuildingID building)
{
auto name = t->town->buildings.at(building)->getNameTranslated();
auto name = t->getTown()->buildings.at(building)->getNameTranslated();
logAi->debug("Player %d will build %s in town of %s at %s", ai->playerID, name, t->getNameTranslated(), t->anchorPos().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)->getNameTranslated(), t->getNameTranslated(), t->anchorPos().toString());
playerID, t->getTown()->buildings.at(b)->getNameTranslated(), t->getNameTranslated(), t->anchorPos().toString());
cb->buildBuilding(t, b);
throw goalFulfilledException(sptr(g));
}

View File

@ -319,7 +319,7 @@ void CCallback::recruitHero(const CGObjectInstance *townOrTavern, const CGHeroIn
assert(townOrTavern);
assert(hero);
HireHero pack(hero->getHeroType(), townOrTavern->id, nextHero);
HireHero pack(hero->getHeroTypeID(), townOrTavern->id, nextHero);
pack.player = *player;
sendRequest(pack);
}

View File

@ -1138,7 +1138,7 @@ void CPlayerInterface::showMapObjectSelectDialog(QueryID askID, const Component
const CGTownInstance * t = dynamic_cast<const CGTownInstance *>(cb->getObj(obj));
if(t)
{
auto image = GH.renderHandler().loadImage(AnimationPath::builtin("ITPA"), t->town->clientInfo.icons[t->hasFort()][false] + 2, 0, EImageBlitMode::OPAQUE);
auto image = GH.renderHandler().loadImage(AnimationPath::builtin("ITPA"), t->getTown()->clientInfo.icons[t->hasFort()][false] + 2, 0, EImageBlitMode::OPAQUE);
image->scaleTo(Point(35, 23));
images.push_back(image);
}

View File

@ -453,7 +453,7 @@ void ClientCommandManager::handleTellCommand(std::istringstream& singleWordBuffe
if(what == "hs")
{
for(const CGHeroInstance* h : LOCPLINT->cb->getHeroesInfo())
if(h->type->getIndex() == id1)
if(h->getHeroTypeID().getNum() == id1)
if(const CArtifactInstance* a = h->getArt(ArtifactPosition(id2)))
printCommandMessage(a->nodeName());
}

View File

@ -671,7 +671,7 @@ void ApplyClientNetPackVisitor::visitSetHeroesInTown(SetHeroesInTown & pack)
void ApplyClientNetPackVisitor::visitHeroRecruited(HeroRecruited & pack)
{
CGHeroInstance *h = gs.map->heroesOnMap.back();
if(h->getHeroType() != pack.hid)
if(h->getHeroTypeID() != pack.hid)
{
logNetwork->error("Something wrong with hero recruited!");
}

View File

@ -432,7 +432,7 @@ std::shared_ptr<CIntObject> CTownList::CTownItem::genSelection()
void CTownList::CTownItem::update()
{
size_t iconIndex = town->town->clientInfo.icons[town->hasFort()][town->built >= LOCPLINT->cb->getSettings().getInteger(EGameSettings::TOWNS_BUILDINGS_PER_TURN_CAP)];
size_t iconIndex = town->getTown()->clientInfo.icons[town->hasFort()][town->built >= LOCPLINT->cb->getSettings().getInteger(EGameSettings::TOWNS_BUILDINGS_PER_TURN_CAP)];
picture->setFrame(iconIndex + 2);
redraw();

View File

@ -389,13 +389,13 @@ BattleHero::BattleHero(const BattleInterface & owner, const CGHeroInstance * her
{
AnimationPath animationPath;
if(!hero->type->battleImage.empty())
animationPath = hero->type->battleImage;
if(!hero->getHeroType()->battleImage.empty())
animationPath = hero->getHeroType()->battleImage;
else
if(hero->gender == EHeroGender::FEMALE)
animationPath = hero->type->heroClass->imageBattleFemale;
animationPath = hero->getHeroClass()->imageBattleFemale;
else
animationPath = hero->type->heroClass->imageBattleMale;
animationPath = hero->getHeroClass()->imageBattleMale;
animation = GH.renderHandler().loadAnimation(animationPath, EImageBlitMode::ALPHA);
@ -1027,7 +1027,7 @@ void StackQueue::update()
int32_t StackQueue::getSiegeShooterIconID()
{
return owner.siegeController->getSiegedTown()->town->faction->getIndex();
return owner.siegeController->getSiegedTown()->getFactionID().getNum();
}
std::optional<uint32_t> StackQueue::getHoveredUnitIdIfAny() const

View File

@ -58,14 +58,14 @@ ImagePath BattleSiegeController::getWallPieceImageName(EWallVisual::EWallVisual
};
};
const std::string & prefix = town->town->clientInfo.siegePrefix;
const std::string & prefix = town->getTown()->clientInfo.siegePrefix;
std::string addit = std::to_string(getImageIndex());
switch(what)
{
case EWallVisual::BACKGROUND_WALL:
{
auto faction = town->town->faction->getIndex();
auto faction = town->getFactionID();
if (faction == ETownType::RAMPART || faction == ETownType::NECROPOLIS || faction == ETownType::DUNGEON || faction == ETownType::STRONGHOLD)
return ImagePath::builtinTODO(prefix + "TPW1.BMP");
@ -111,7 +111,7 @@ ImagePath BattleSiegeController::getWallPieceImageName(EWallVisual::EWallVisual
void BattleSiegeController::showWallPiece(Canvas & canvas, EWallVisual::EWallVisual what)
{
auto & ci = town->town->clientInfo;
auto & ci = town->getTown()->clientInfo;
auto const & pos = ci.siegePositions[what];
if ( wallPieceImages[what] && pos.isValid())
@ -120,7 +120,7 @@ void BattleSiegeController::showWallPiece(Canvas & canvas, EWallVisual::EWallVis
ImagePath BattleSiegeController::getBattleBackgroundName() const
{
const std::string & prefix = town->town->clientInfo.siegePrefix;
const std::string & prefix = town->getTown()->clientInfo.siegePrefix;
return ImagePath::builtinTODO(prefix + "BACK.BMP");
}
@ -130,8 +130,8 @@ bool BattleSiegeController::getWallPieceExistence(EWallVisual::EWallVisual what)
switch (what)
{
case EWallVisual::MOAT: return fortifications.hasMoat && town->town->clientInfo.siegePositions.at(EWallVisual::MOAT).isValid();
case EWallVisual::MOAT_BANK: return fortifications.hasMoat && town->town->clientInfo.siegePositions.at(EWallVisual::MOAT_BANK).isValid();
case EWallVisual::MOAT: return fortifications.hasMoat && town->getTown()->clientInfo.siegePositions.at(EWallVisual::MOAT).isValid();
case EWallVisual::MOAT_BANK: return fortifications.hasMoat && town->getTown()->clientInfo.siegePositions.at(EWallVisual::MOAT_BANK).isValid();
case EWallVisual::KEEP_BATTLEMENT: return fortifications.citadelHealth > 0 && owner.getBattle()->battleGetWallState(EWallPart::KEEP) != EWallState::DESTROYED;
case EWallVisual::UPPER_BATTLEMENT: return fortifications.upperTowerHealth > 0 && owner.getBattle()->battleGetWallState(EWallPart::UPPER_TOWER) != EWallState::DESTROYED;
case EWallVisual::BOTTOM_BATTLEMENT: return fortifications.lowerTowerHealth > 0 && owner.getBattle()->battleGetWallState(EWallPart::BOTTOM_TOWER) != EWallState::DESTROYED;
@ -218,8 +218,8 @@ Point BattleSiegeController::getTurretCreaturePosition( BattleHex position ) con
if (posID != 0)
{
return {
town->town->clientInfo.siegePositions[posID].x,
town->town->clientInfo.siegePositions[posID].y
town->getTown()->clientInfo.siegePositions[posID].x,
town->getTown()->clientInfo.siegePositions[posID].y
};
}

View File

@ -468,8 +468,8 @@ void CInteractableTownTooltip::init(const CGTownInstance * town)
LOCPLINT->showTavernWindow(town, nullptr, QueryID::NONE);
}
}, [town]{
if(!town->town->faction->getDescriptionTranslated().empty())
CRClickPopup::createAndPush(town->town->faction->getDescriptionTranslated());
if(!town->getFaction()->getDescriptionTranslated().empty())
CRClickPopup::createAndPush(town->getFaction()->getDescriptionTranslated());
});
fastMarket = std::make_shared<LRClickableArea>(Rect(143, 31, 30, 34), []()
{
@ -532,8 +532,7 @@ CreatureTooltip::CreatureTooltip(Point pos, const CGCreature * creature)
{
OBJECT_CONSTRUCTION;
auto creatureID = creature->getCreature();
int32_t creatureIconIndex = CGI->creatures()->getById(creatureID)->getIconIndex();
int32_t creatureIconIndex = creature->getCreature()->getIconIndex();
creatureImage = std::make_shared<CAnimImage>(AnimationPath::builtin("TWCRPORT"), creatureIconIndex);
creatureImage->center(Point(parent->pos.x + parent->pos.w / 2, parent->pos.y + creatureImage->pos.h / 2 + 11));
@ -633,7 +632,7 @@ CCreaturePic::CCreaturePic(int x, int y, const CCreature * cre, bool Big, bool A
pos.x+=x;
pos.y+=y;
auto faction = cre->getFaction();
auto faction = cre->getFactionID();
assert(CGI->townh->size() > faction);

View File

@ -82,7 +82,7 @@ CBuildingRect::CBuildingRect(CCastleBuildings * Par, const CGTownInstance * Town
// special animation frame manipulation for castle shipyard with and without ship
// done due to .def used in special way, not to animate building - first image is for shipyard without citadel moat, 2nd image is for including moat
if(Town->town->faction->getId() == FactionID::CASTLE && Str->building &&
if(Town->getFactionID() == FactionID::CASTLE && Str->building &&
(Str->building->bid == BuildingID::SHIPYARD || Str->building->bid == BuildingID::SHIP))
{
if(Town->hasBuilt(BuildingID::CITADEL))
@ -107,7 +107,7 @@ const CBuilding * CBuildingRect::getBuilding()
return nullptr;
if (str->hiddenUpgrade) // hidden upgrades, e.g. hordes - return base (dwelling for hordes)
return town->town->buildings.at(str->building->getBase());
return town->getTown()->buildings.at(str->building->getBase());
return str->building;
}
@ -156,7 +156,7 @@ void CBuildingRect::showPopupWindow(const Point & cursorPosition)
return;
BuildingID bid = getBuilding()->bid;
const CBuilding *bld = town->town->buildings.at(bid);
const CBuilding *bld = town->getTown()->buildings.at(bid);
if (bid < BuildingID::DWELL_FIRST)
{
CRClickPopup::createAndPush(CInfoWindow::genText(bld->getNameTranslated(), bld->getDescriptionTranslated()),
@ -235,10 +235,10 @@ std::string CBuildingRect::getSubtitle()//hover text for building
int bid = getBuilding()->bid;
if (bid<30)//non-dwellings - only building name
return town->town->buildings.at(getBuilding()->bid)->getNameTranslated();
return town->getTown()->buildings.at(getBuilding()->bid)->getNameTranslated();
else//dwellings - recruit %creature%
{
auto & availableCreatures = town->creatures[(bid-30)%town->town->creatures.size()].second;
auto & availableCreatures = town->creatures[(bid-30)%town->getTown()->creatures.size()].second;
if(availableCreatures.size())
{
int creaID = availableCreatures.back();//taking last of available creatures
@ -566,7 +566,7 @@ CCastleBuildings::CCastleBuildings(const CGTownInstance* Town):
{
OBJECT_CONSTRUCTION;
background = std::make_shared<CPicture>(town->town->clientInfo.townBackground);
background = std::make_shared<CPicture>(town->getTown()->clientInfo.townBackground);
background->needRefresh = true;
background->getSurface()->setBlitMode(EImageBlitMode::OPAQUE);
pos.w = background->pos.w;
@ -602,7 +602,7 @@ void CCastleBuildings::recreate()
}
}
for(const CStructure * structure : town->town->clientInfo.structures)
for(const CStructure * structure : town->getTown()->clientInfo.structures)
{
if(!structure->building)
{
@ -617,7 +617,7 @@ void CCastleBuildings::recreate()
for(auto & entry : groups)
{
const CBuilding * build = town->town->buildings.at(entry.first);
const CBuilding * build = town->getTown()->buildings.at(entry.first);
const CStructure * toAdd = *boost::max_element(entry.second, [=](const CStructure * a, const CStructure * b)
{
@ -648,7 +648,7 @@ void CCastleBuildings::recreate()
void CCastleBuildings::addBuilding(BuildingID building)
{
//FIXME: implement faster method without complete recreation of town
BuildingID base = town->town->buildings.at(building)->getBase();
BuildingID base = town->getTown()->buildings.at(building)->getBase();
recreate();
@ -687,7 +687,7 @@ void CCastleBuildings::buildingClicked(BuildingID building)
BuildingID buildingToEnter = building;
for(;;)
{
const CBuilding *b = town->town->buildings.find(buildingToEnter)->second;
const CBuilding *b = town->getTown()->buildings.find(buildingToEnter)->second;
if (buildingTryActivateCustomUI(buildingToEnter, building))
return;
@ -705,7 +705,7 @@ void CCastleBuildings::buildingClicked(BuildingID building)
bool CCastleBuildings::buildingTryActivateCustomUI(BuildingID buildingToTest, BuildingID buildingTarget)
{
logGlobal->trace("You've clicked on %d", (int)buildingToTest.toEnum());
const CBuilding *b = town->town->buildings.at(buildingToTest);
const CBuilding *b = town->getTown()->buildings.at(buildingToTest);
if (town->getWarMachineInBuilding(buildingToTest).hasValue())
{
@ -744,7 +744,7 @@ bool CCastleBuildings::buildingTryActivateCustomUI(BuildingID buildingToTest, Bu
}
}
if (town->rewardableBuildings.count(buildingToTest) && town->town->buildings.at(buildingToTest)->manualHeroVisit)
if (town->rewardableBuildings.count(buildingToTest) && town->getTown()->buildings.at(buildingToTest)->manualHeroVisit)
{
enterRewardable(buildingToTest);
return true;
@ -820,10 +820,10 @@ bool CCastleBuildings::buildingTryActivateCustomUI(BuildingID buildingToTest, Bu
return false;
case BuildingSubID::PORTAL_OF_SUMMONING:
if (town->creatures[town->town->creatures.size()].second.empty())//No creatures
if (town->creatures[town->getTown()->creatures.size()].second.empty())//No creatures
LOCPLINT->showInfoDialog(CGI->generaltexth->tcommands[30]);
else
enterDwelling(town->town->creatures.size());
enterDwelling(town->getTown()->creatures.size());
return true;
case BuildingSubID::BANK:
@ -850,7 +850,7 @@ void CCastleBuildings::enterRewardable(BuildingID building)
{
MetaString message;
message.appendTextID("core.genrltxt.273"); // only visiting heroes may visit %s
message.replaceTextID(town->town->buildings.at(building)->getNameTextID());
message.replaceTextID(town->getTown()->buildings.at(building)->getNameTextID());
LOCPLINT->showInfoDialog(message.toString());
}
@ -868,7 +868,7 @@ void CCastleBuildings::enterBlacksmith(BuildingID building, ArtifactID artifactI
const CGHeroInstance *hero = town->visitingHero;
if(!hero)
{
LOCPLINT->showInfoDialog(boost::str(boost::format(CGI->generaltexth->allTexts[273]) % town->town->buildings.find(building)->second->getNameTranslated()));
LOCPLINT->showInfoDialog(boost::str(boost::format(CGI->generaltexth->allTexts[273]) % town->getTown()->buildings.find(building)->second->getNameTranslated()));
return;
}
auto art = artifactID.toArtifact();
@ -897,8 +897,8 @@ void CCastleBuildings::enterBlacksmith(BuildingID building, ArtifactID artifactI
void CCastleBuildings::enterBuilding(BuildingID building)
{
std::vector<std::shared_ptr<CComponent>> comps(1, std::make_shared<CComponent>(ComponentType::BUILDING, BuildingTypeUniqueID(town->getFaction(), building)));
LOCPLINT->showInfoDialog( town->town->buildings.find(building)->second->getDescriptionTranslated(), comps);
std::vector<std::shared_ptr<CComponent>> comps(1, std::make_shared<CComponent>(ComponentType::BUILDING, BuildingTypeUniqueID(town->getFactionID(), building)));
LOCPLINT->showInfoDialog( town->getTown()->buildings.find(building)->second->getDescriptionTranslated(), comps);
}
void CCastleBuildings::enterCastleGate()
@ -915,20 +915,20 @@ 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->getId() == town->town->faction->getId() && //the town of the same faction
t->getFactionID() == town->getFactionID() && //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
if(settings["general"]["enableUiEnhancements"].Bool())
{
auto image = GH.renderHandler().loadImage(AnimationPath::builtin("ITPA"), t->town->clientInfo.icons[t->hasFort()][false] + 2, 0, EImageBlitMode::OPAQUE);
auto image = GH.renderHandler().loadImage(AnimationPath::builtin("ITPA"), t->getTown()->clientInfo.icons[t->hasFort()][false] + 2, 0, EImageBlitMode::OPAQUE);
image->scaleTo(Point(35, 23));
images.push_back(image);
}
}
}
auto gateIcon = std::make_shared<CAnimImage>(town->town->clientInfo.buildingsIcons, BuildingID::CASTLE_GATE);//will be deleted by selection window
auto gateIcon = std::make_shared<CAnimImage>(town->getTown()->clientInfo.buildingsIcons, BuildingID::CASTLE_GATE);//will be deleted by selection window
auto wnd = std::make_shared<CObjectListWindow>(availableTowns, gateIcon, CGI->generaltexth->jktexts[40],
CGI->generaltexth->jktexts[41], std::bind (&CCastleInterface::castleTeleport, LOCPLINT->castleInt, _1), 0, images);
wnd->onPopup = [availableTowns](int index) { CRClickPopup::createAndPush(LOCPLINT->cb->getObjInstance(ObjectInstanceID(availableTowns[index])), GH.getCursorPosition()); };
@ -940,7 +940,7 @@ void CCastleBuildings::enterDwelling(int level)
if (level < 0 || level >= town->creatures.size() || town->creatures[level].second.empty())
{
assert(0);
logGlobal->error("Attempt to enter into invalid dwelling of level %d in town %s (%s)", level, town->getNameTranslated(), town->town->faction->getNameTranslated());
logGlobal->error("Attempt to enter into invalid dwelling of level %d in town %s (%s)", level, town->getNameTranslated(), town->getFaction()->getNameTranslated());
return;
}
@ -954,8 +954,8 @@ void CCastleBuildings::enterDwelling(int level)
void CCastleBuildings::enterToTheQuickRecruitmentWindow()
{
const auto beginIt = town->creatures.cbegin();
const auto afterLastIt = town->creatures.size() > town->town->creatures.size()
? std::next(beginIt, town->town->creatures.size())
const auto afterLastIt = town->creatures.size() > town->getTown()->creatures.size()
? std::next(beginIt, town->getTown()->creatures.size())
: town->creatures.cend();
const auto hasSomeoneToRecruit = std::any_of(beginIt, afterLastIt,
[](const auto & creatureInfo) { return creatureInfo.first > 0; });
@ -967,8 +967,8 @@ void CCastleBuildings::enterToTheQuickRecruitmentWindow()
void CCastleBuildings::enterFountain(const BuildingID & building, BuildingSubID::EBuildingSubID subID, BuildingID upgrades)
{
std::vector<std::shared_ptr<CComponent>> comps(1, std::make_shared<CComponent>(ComponentType::BUILDING, BuildingTypeUniqueID(town->getFaction(), building)));
std::string descr = town->town->buildings.find(building)->second->getDescriptionTranslated();
std::vector<std::shared_ptr<CComponent>> comps(1, std::make_shared<CComponent>(ComponentType::BUILDING, BuildingTypeUniqueID(town->getFactionID(), building)));
std::string descr = town->getTown()->buildings.find(building)->second->getDescriptionTranslated();
std::string hasNotProduced;
std::string hasProduced;
@ -977,10 +977,10 @@ void CCastleBuildings::enterFountain(const BuildingID & building, BuildingSubID:
bool isMysticPondOrItsUpgrade = subID == BuildingSubID::MYSTIC_POND
|| (upgrades != BuildingID::NONE
&& town->town->buildings.find(BuildingID(upgrades))->second->subId == BuildingSubID::MYSTIC_POND);
&& town->getTown()->buildings.find(BuildingID(upgrades))->second->subId == BuildingSubID::MYSTIC_POND);
if(upgrades != BuildingID::NONE)
descr += "\n\n"+town->town->buildings.find(BuildingID(upgrades))->second->getDescriptionTranslated();
descr += "\n\n"+town->getTown()->buildings.find(BuildingID(upgrades))->second->getDescriptionTranslated();
if(isMysticPondOrItsUpgrade) //for vanila Rampart like towns
{
@ -1056,7 +1056,7 @@ void CCastleBuildings::enterTownHall()
void CCastleBuildings::openMagesGuild()
{
auto mageGuildBackground = LOCPLINT->castleInt->town->town->clientInfo.guildBackground;
auto mageGuildBackground = LOCPLINT->castleInt->town->getTown()->clientInfo.guildBackground;
GH.windows().createAndPushWindow<CMageGuildScreen>(LOCPLINT->castleInt, mageGuildBackground);
}
@ -1247,7 +1247,7 @@ CTownInfo::CTownInfo(int posX, int posY, const CGTownInstance * Town, bool townH
return;//FIXME: suspicious statement, fix or comment
picture = std::make_shared<CAnimImage>(AnimationPath::builtin("ITMCL.DEF"), town->fortLevel()-1);
}
building = town->town->buildings.at(BuildingID(buildID));
building = town->getTown()->buildings.at(BuildingID(buildID));
pos = picture->pos;
}
@ -1322,7 +1322,7 @@ CCastleInterface::CCastleInterface(const CGTownInstance * Town, const CGTownInst
recreateIcons();
if (!from)
adventureInt->onAudioPaused();
CCS->musich->playMusicFromSet("faction", town->town->faction->getJsonKey(), true, false);
CCS->musich->playMusicFromSet("faction", town->getFaction()->getJsonKey(), true, false);
}
CCastleInterface::~CCastleInterface()
@ -1403,7 +1403,7 @@ void CCastleInterface::removeBuilding(BuildingID bid)
void CCastleInterface::recreateIcons()
{
OBJECT_CONSTRUCTION;
size_t iconIndex = town->town->clientInfo.icons[town->hasFort()][town->built >= LOCPLINT->cb->getSettings().getInteger(EGameSettings::TOWNS_BUILDINGS_PER_TURN_CAP)];
size_t iconIndex = town->getTown()->clientInfo.icons[town->hasFort()][town->built >= LOCPLINT->cb->getSettings().getInteger(EGameSettings::TOWNS_BUILDINGS_PER_TURN_CAP)];
icon->setFrame(iconIndex);
TResources townIncome = town->dailyIncome();
@ -1425,8 +1425,8 @@ void CCastleInterface::recreateIcons()
if(town->hasBuilt(BuildingID::TAVERN))
LOCPLINT->showTavernWindow(town, nullptr, QueryID::NONE);
}, [this]{
if(!town->town->faction->getDescriptionTranslated().empty())
CRClickPopup::createAndPush(town->town->faction->getDescriptionTranslated());
if(!town->getFaction()->getDescriptionTranslated().empty())
CRClickPopup::createAndPush(town->getFaction()->getDescriptionTranslated());
});
creainfo.clear();
@ -1527,7 +1527,7 @@ CHallInterface::CBuildingBox::CBuildingBox(int x, int y, const CGTownInstance *
-1, -1, -1, 0, 0, 1, 2, -1, 1, 1, -1, -1
};
icon = std::make_shared<CAnimImage>(town->town->clientInfo.buildingsIcons, building->bid, 0, 2, 2);
icon = std::make_shared<CAnimImage>(town->getTown()->clientInfo.buildingsIcons, building->bid, 0, 2, 2);
header = std::make_shared<CAnimImage>(AnimationPath::builtin("TPTHBAR"), panelIndex[static_cast<int>(state)], 0, 1, 73);
if(iconIndex[static_cast<int>(state)] >=0)
mark = std::make_shared<CAnimImage>(AnimationPath::builtin("TPTHCHK"), iconIndex[static_cast<int>(state)], 0, 136, 56);
@ -1569,7 +1569,7 @@ void CHallInterface::CBuildingBox::showPopupWindow(const Point & cursorPosition)
}
CHallInterface::CHallInterface(const CGTownInstance * Town):
CWindowObject(PLAYER_COLORED | BORDERED, Town->town->clientInfo.hallBackground),
CWindowObject(PLAYER_COLORED | BORDERED, Town->getTown()->clientInfo.hallBackground),
town(Town)
{
OBJECT_CONSTRUCTION;
@ -1581,10 +1581,10 @@ CHallInterface::CHallInterface(const CGTownInstance * Town):
auto statusbarBackground = std::make_shared<CPicture>(background->getSurface(), barRect, 5, 556);
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))->getNameTranslated());
title = std::make_shared<CLabel>(399, 12, FONT_MEDIUM, ETextAlignment::CENTER, Colors::WHITE, town->getTown()->buildings.at(BuildingID(town->hallLevel()+BuildingID::VILLAGE_HALL))->getNameTranslated());
exit = std::make_shared<CButton>(Point(748, 556), AnimationPath::builtin("TPMAGE1.DEF"), CButton::tooltip(CGI->generaltexth->hcommands[8]), [&](){close();}, EShortcut::GLOBAL_RETURN);
auto & boxList = town->town->clientInfo.hallSlots;
auto & boxList = town->getTown()->clientInfo.hallSlots;
boxes.resize(boxList.size());
for(size_t row=0; row<boxList.size(); row++) //for each row
{
@ -1595,11 +1595,11 @@ CHallInterface::CHallInterface(const CGTownInstance * Town):
{
if (!buildingID.hasValue())
{
logMod->warn("Invalid building ID found in hallSlots of town '%s'", town->town->faction->getJsonKey() );
logMod->warn("Invalid building ID found in hallSlots of town '%s'", town->getFaction()->getJsonKey() );
continue;
}
const CBuilding * current = town->town->buildings.at(buildingID);
const CBuilding * current = town->getTown()->buildings.at(buildingID);
if(town->hasBuilt(buildingID))
{
building = current;
@ -1629,7 +1629,7 @@ CBuildWindow::CBuildWindow(const CGTownInstance *Town, const CBuilding * Buildin
{
OBJECT_CONSTRUCTION;
icon = std::make_shared<CAnimImage>(town->town->clientInfo.buildingsIcons, building->bid, 0, 125, 50);
icon = std::make_shared<CAnimImage>(town->getTown()->clientInfo.buildingsIcons, building->bid, 0, 125, 50);
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);
@ -1711,7 +1711,7 @@ std::string CBuildWindow::getTextForState(EBuildingState state)
{
auto toStr = [&](const BuildingID build) -> std::string
{
return town->town->buildings.at(build)->getNameTranslated();
return town->getTown()->buildings.at(build)->getNameTranslated();
};
ret = CGI->generaltexth->allTexts[52];
@ -1721,7 +1721,7 @@ std::string CBuildWindow::getTextForState(EBuildingState 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)->getNameTranslated());
ret = boost::str(boost::format(msg) % town->getTown()->buildings.at(building->upgrade)->getNameTranslated());
break;
}
}
@ -1780,11 +1780,11 @@ CFortScreen::CFortScreen(const CGTownInstance * town):
{
OBJECT_CONSTRUCTION;
ui32 fortSize = static_cast<ui32>(town->creatures.size());
if(fortSize > town->town->creatures.size() && town->creatures.back().second.empty())
if(fortSize > town->getTown()->creatures.size() && town->creatures.back().second.empty())
fortSize--;
fortSize = std::min(fortSize, static_cast<ui32>(GameConstants::CREATURES_PER_TOWN)); // for 8 creatures + portal of summoning
const CBuilding * fortBuilding = town->town->buildings.at(BuildingID(town->fortLevel()+6));
const CBuilding * fortBuilding = town->getTown()->buildings.at(BuildingID(town->fortLevel()+6));
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->getNameTranslated());
@ -1810,7 +1810,7 @@ CFortScreen::CFortScreen(const CGTownInstance * town):
for(ui32 i=0; i<fortSize; i++)
{
BuildingID buildingID;
if(fortSize == town->town->creatures.size())
if(fortSize == town->getTown()->creatures.size())
{
BuildingID dwelling = BuildingID::getDwellingFromLevel(i, 1);
@ -1839,7 +1839,7 @@ CFortScreen::CFortScreen(const CGTownInstance * town):
ImagePath CFortScreen::getBgName(const CGTownInstance * town)
{
ui32 fortSize = static_cast<ui32>(town->creatures.size());
if(fortSize > town->town->creatures.size() && town->creatures.back().second.empty())
if(fortSize > town->getTown()->creatures.size() && town->creatures.back().second.empty())
fortSize--;
fortSize = std::min(fortSize, static_cast<ui32>(GameConstants::CREATURES_PER_TOWN)); // for 8 creatures + portal of summoning
@ -1877,7 +1877,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);
buildingIcon = std::make_shared<CAnimImage>(town->getTown()->clientInfo.buildingsIcons, getMyBuilding()->bid, 0, 4, 21);
buildingName = std::make_shared<CLabel>(78, 101, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE, getMyBuilding()->getNameTranslated(), 152);
if(town->hasBuilt(getMyBuilding()->bid))
@ -1913,8 +1913,8 @@ const CCreature * CFortScreen::RecruitArea::getMyCreature()
{
if(!town->creatures.at(level).second.empty()) // built
return town->creatures.at(level).second.back().toCreature();
if(!town->town->creatures.at(level).empty()) // there are creatures on this level
return town->town->creatures.at(level).front().toCreature();
if(!town->getTown()->creatures.at(level).empty()) // there are creatures on this level
return town->getTown()->creatures.at(level).front().toCreature();
return nullptr;
}
@ -1922,17 +1922,17 @@ const CBuilding * CFortScreen::RecruitArea::getMyBuilding()
{
BuildingID myID = BuildingID(BuildingID::getDwellingFromLevel(level, 0));
if (level == town->town->creatures.size())
return town->town->getSpecialBuilding(BuildingSubID::PORTAL_OF_SUMMONING);
if (level == town->getTown()->creatures.size())
return town->getTown()->getSpecialBuilding(BuildingSubID::PORTAL_OF_SUMMONING);
if (!town->town->buildings.count(myID))
if (!town->getTown()->buildings.count(myID))
return nullptr;
const CBuilding * build = town->town->buildings.at(myID);
while (town->town->buildings.count(myID))
const CBuilding * build = town->getTown()->buildings.at(myID);
while (town->getTown()->buildings.count(myID))
{
if (town->hasBuilt(myID))
build = town->town->buildings.at(myID);
build = town->getTown()->buildings.at(myID);
BuildingID::advanceDwelling(myID);
}
@ -1972,7 +1972,7 @@ CMageGuildScreen::CMageGuildScreen(CCastleInterface * owner, const ImagePath & i
{
OBJECT_CONSTRUCTION;
window = std::make_shared<CPicture>(owner->town->town->clientInfo.guildWindow, 332, 76);
window = std::make_shared<CPicture>(owner->town->getTown()->clientInfo.guildWindow, 332, 76);
resdatabar = std::make_shared<CMinorResDataBar>();
resdatabar->moveBy(pos.topLeft(), true);
@ -2007,7 +2007,7 @@ void CMageGuildScreen::updateSpells(ObjectInstanceID tID)
const CGTownInstance * town = LOCPLINT->cb->getTown(townId);
for(size_t i=0; i<town->town->mageLevel; i++)
for(size_t i=0; i<town->getTown()->mageLevel; i++)
{
size_t spellCount = town->spellsAtLevel((int)i+1,false); //spell at level with -1 hmmm?
for(size_t j=0; j<spellCount; j++)

View File

@ -84,7 +84,7 @@ CExchangeWindow::CExchangeWindow(ObjectInstanceID hero1, ObjectInstanceID hero2,
for(int m=0; m < hero->secSkills.size(); ++m)
secSkillIcons[leftRight].push_back(std::make_shared<CAnimImage>(AnimationPath::builtin("SECSK32"), 0, 0, 32 + 36 * m + 454 * leftRight, qeLayout ? 83 : 88));
specImages[leftRight] = std::make_shared<CAnimImage>(AnimationPath::builtin("UN32"), hero->type->imageIndex, 0, 67 + 490 * leftRight, qeLayout ? 41 : 45);
specImages[leftRight] = std::make_shared<CAnimImage>(AnimationPath::builtin("UN32"), hero->getHeroType()->imageIndex, 0, 67 + 490 * leftRight, qeLayout ? 41 : 45);
expImages[leftRight] = std::make_shared<CAnimImage>(AnimationPath::builtin("PSKIL32"), 4, 0, 103 + 490 * leftRight, qeLayout ? 41 : 45);
expValues[leftRight] = std::make_shared<CLabel>(119 + 490 * leftRight, qeLayout ? 66 : 71, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE);
@ -151,7 +151,7 @@ CExchangeWindow::CExchangeWindow(ObjectInstanceID hero1, ObjectInstanceID hero2,
specialtyAreas[b] = std::make_shared<LRClickableAreaWText>();
specialtyAreas[b]->pos = Rect(Point(pos.x + 69 + 490 * b, pos.y + (qeLayout ? 41 : 45)), Point(32, 32));
specialtyAreas[b]->hoverText = CGI->generaltexth->heroscrn[27];
specialtyAreas[b]->text = hero->type->getSpecialtyDescriptionTranslated();
specialtyAreas[b]->text = hero->getHeroType()->getSpecialtyDescriptionTranslated();
experienceAreas[b] = std::make_shared<LRClickableAreaWText>();
experienceAreas[b]->pos = Rect(Point(pos.x + 105 + 490 * b, pos.y + (qeLayout ? 41 : 45)), Point(32, 32));

View File

@ -184,9 +184,9 @@ void CHeroWindow::update()
name->setText(curHero->getNameTranslated());
title->setText((boost::format(CGI->generaltexth->allTexts[342]) % curHero->level % curHero->getClassNameTranslated()).str());
specArea->text = curHero->type->getSpecialtyDescriptionTranslated();
specImage->setFrame(curHero->type->imageIndex);
specName->setText(curHero->type->getSpecialtyNameTranslated());
specArea->text = curHero->getHeroType()->getSpecialtyDescriptionTranslated();
specImage->setFrame(curHero->getHeroType()->imageIndex);
specName->setText(curHero->getHeroType()->getSpecialtyNameTranslated());
tacticsButton = std::make_shared<CToggleButton>(Point(539, 483), AnimationPath::builtin("hsbtns8.def"), std::make_pair(heroscrn[26], heroscrn[31]), 0, EShortcut::HERO_TOGGLE_TACTICS);
tacticsButton->addHoverText(EButtonState::HIGHLIGHTED, CGI->generaltexth->heroscrn[25]);

View File

@ -300,7 +300,7 @@ int InfoBoxHeroData::getSubID()
else
return 0;
case HERO_SPECIAL:
return hero->type->getIndex();
return hero->getHeroTypeID().getNum();
case HERO_MANA:
case HERO_EXPERIENCE:
return 0;
@ -800,7 +800,7 @@ CTownItem::CTownItem(const CGTownInstance * Town)
garr = std::make_shared<CGarrisonInt>(Point(313, 3), 4, Point(232,0), town->getUpperArmy(), town->visitingHero, true, true, CGarrisonInt::ESlotsLayout::TWO_ROWS);
heroes = std::make_shared<HeroSlots>(town, Point(244,6), Point(475,6), garr, false);
size_t iconIndex = town->town->clientInfo.icons[town->hasFort()][town->built >= LOCPLINT->cb->getSettings().getInteger(EGameSettings::TOWNS_BUILDINGS_PER_TURN_CAP)];
size_t iconIndex = town->getTown()->clientInfo.icons[town->hasFort()][town->built >= LOCPLINT->cb->getSettings().getInteger(EGameSettings::TOWNS_BUILDINGS_PER_TURN_CAP)];
picture = std::make_shared<CAnimImage>(AnimationPath::builtin("ITPT"), iconIndex, 0, 5, 6);
openTown = std::make_shared<LRClickableAreaOpenTown>(Rect(5, 6, 58, 64), town);
@ -823,8 +823,8 @@ CTownItem::CTownItem(const CGTownInstance * Town)
if(town->hasBuilt(BuildingID::TAVERN))
LOCPLINT->showTavernWindow(town, nullptr, QueryID::NONE);
}, [&]{
if(!town->town->faction->getDescriptionTranslated().empty())
CRClickPopup::createAndPush(town->town->faction->getDescriptionTranslated());
if(!town->getTown()->faction->getDescriptionTranslated().empty())
CRClickPopup::createAndPush(town->getFaction()->getDescriptionTranslated());
});
fastMarket = std::make_shared<LRClickableArea>(Rect(153, 6, 65, 64), []()
{

View File

@ -192,7 +192,7 @@ std::string CMarketWindow::getMarketTitle(const ObjectInstanceID marketId, const
{
for(const auto & buildingId : town->getBuildings())
{
if(const auto building = town->town->buildings.at(buildingId); vstd::contains(building->marketModes, mode))
if(const auto building = town->getTown()->buildings.at(buildingId); vstd::contains(building->marketModes, mode))
return building->getNameTranslated();
}
}

View File

@ -522,9 +522,9 @@ CTavernWindow::CTavernWindow(const CGObjectInstance * TavernObj, const std::func
recruit->block(true);
}
if(LOCPLINT->castleInt)
videoPlayer = std::make_shared<VideoWidget>(Point(70, 56), LOCPLINT->castleInt->town->town->clientInfo.tavernVideo, false);
videoPlayer = std::make_shared<VideoWidget>(Point(70, 56), LOCPLINT->castleInt->town->getTown()->clientInfo.tavernVideo, false);
else if(const auto * townObj = dynamic_cast<const CGTownInstance *>(TavernObj))
videoPlayer = std::make_shared<VideoWidget>(Point(70, 56), townObj->town->clientInfo.tavernVideo, false);
videoPlayer = std::make_shared<VideoWidget>(Point(70, 56), townObj->getTown()->clientInfo.tavernVideo, false);
else
videoPlayer = std::make_shared<VideoWidget>(Point(70, 56), VideoPath::builtin("TAVERN.BIK"), false);
@ -548,7 +548,7 @@ void CTavernWindow::addInvite()
if(!inviteableHeroes.empty())
{
int imageIndex = heroToInvite ? (*CGI->heroh)[heroToInvite->getHeroType()]->imageIndex : 156; // 156 => special id for random
int imageIndex = heroToInvite ? heroToInvite->getIconIndex() : 156; // 156 => special id for random
if(!heroToInvite)
heroToInvite = (*RandomGeneratorUtil::nextItem(inviteableHeroes, CRandomGenerator::getDefault())).second;
@ -563,7 +563,7 @@ void CTavernWindow::recruitb()
const CGHeroInstance *toBuy = (selected ? h2 : h1)->h;
const CGObjectInstance *obj = tavernObj;
LOCPLINT->cb->recruitHero(obj, toBuy, heroToInvite ? heroToInvite->getHeroType() : HeroTypeID::NONE);
LOCPLINT->cb->recruitHero(obj, toBuy, heroToInvite ? heroToInvite->getHeroTypeID() : HeroTypeID::NONE);
close();
}
@ -963,7 +963,7 @@ CUniversityWindow::CUniversityWindow(const CGHeroInstance * _hero, BuildingID bu
if(auto town = dynamic_cast<const CGTownInstance *>(_market))
{
auto faction = town->town->faction->getId();
auto faction = town->getTown()->faction->getId();
titlePic = std::make_shared<CAnimImage>((*CGI->townh)[faction]->town->clientInfo.buildingsIcons, building);
}
else if(auto uni = dynamic_cast<const CGUniversity *>(_market); uni->appearance)

View File

@ -51,9 +51,9 @@ void QuickRecruitmentWindow::setCreaturePurchaseCards()
{
int availableAmount = getAvailableCreatures();
Point position = Point((pos.w - 100*availableAmount - 8*(availableAmount-1))/2,64);
for (int i = 0; i < town->town->creatures.size(); i++)
for (int i = 0; i < town->getTown()->creatures.size(); i++)
{
if(!town->town->creatures.at(i).empty() && !town->creatures.at(i).second.empty() && town->creatures[i].first)
if(!town->getTown()->creatures.at(i).empty() && !town->creatures.at(i).second.empty() && town->creatures[i].first)
{
cards.push_back(std::make_shared<CreaturePurchaseCard>(town->creatures[i].second, position, town->creatures[i].first, this));
position.x += 108;
@ -108,7 +108,7 @@ void QuickRecruitmentWindow::purchaseUnits()
{
int level = 0;
int i = 0;
for(auto c : town->town->creatures)
for(auto c : town->getTown()->creatures)
{
for(auto c2 : c)
if(c2 == selected->creatureOnTheCard->getId())
@ -129,8 +129,8 @@ void QuickRecruitmentWindow::purchaseUnits()
int QuickRecruitmentWindow::getAvailableCreatures()
{
int creaturesAmount = 0;
for (int i=0; i< town->town->creatures.size(); i++)
if(!town->town->creatures.at(i).empty() && !town->creatures.at(i).second.empty() && town->creatures[i].first)
for (int i=0; i< town->getTown()->creatures.size(); i++)
if(!town->getTown()->creatures.at(i).empty() && !town->creatures.at(i).second.empty() && town->creatures[i].first)
creaturesAmount++;
return creaturesAmount;
}

View File

@ -26,7 +26,7 @@ class DLL_LINKAGE INativeTerrainProvider
{
public:
virtual TerrainId getNativeTerrain() const = 0;
virtual FactionID getFaction() const = 0;
virtual FactionID getFactionID() const = 0;
virtual bool isNativeTerrain(TerrainId terrain) const;
};

View File

@ -38,7 +38,7 @@ TerrainId AFactionMember::getNativeTerrain() const
//this code is used in the CreatureTerrainLimiter::limit to setup battle bonuses
//and in the CGHeroInstance::getNativeTerrain() to setup movement bonuses or/and penalties.
return getBonusBearer()->hasBonus(selectorNoTerrainPenalty, cachingStringNoTerrainPenalty)
? TerrainId::ANY_TERRAIN : VLC->factions()->getById(getFaction())->getNativeTerrain();
? TerrainId::ANY_TERRAIN : getFactionID().toEntity(VLC)->getNativeTerrain();
}
int32_t AFactionMember::magicResistance() const

View File

@ -117,7 +117,7 @@ int32_t CCreature::getHorde() const
return hordeGrowth;
}
FactionID CCreature::getFaction() const
FactionID CCreature::getFactionID() const
{
return FactionID(faction);
}

View File

@ -127,7 +127,7 @@ public:
std::string getNamePluralTextID() const override;
std::string getNameSingularTextID() const override;
FactionID getFaction() const override;
FactionID getFactionID() const override;
int32_t getIndex() const override;
int32_t getIconIndex() const override;
std::string getJsonKey() const override;

View File

@ -912,10 +912,10 @@ void CStackInstance::serializeJson(JsonSerializeFormat & handler)
}
}
FactionID CStackInstance::getFaction() const
FactionID CStackInstance::getFactionID() const
{
if(type)
return type->getFaction();
return type->getFactionID();
return FactionID::NEUTRAL;
}

View File

@ -106,7 +106,7 @@ public:
//IConstBonusProvider
const IBonusBearer* getBonusBearer() const override;
//INativeTerrainProvider
FactionID getFaction() const override;
FactionID getFactionID() const override;
virtual ui64 getPower() const;
CCreature::CreatureQuantityId getQuantityID() const;

View File

@ -381,7 +381,7 @@ bool CGameInfoCallback::getHeroInfo(const CGObjectInstance * hero, InfoAboutHero
for(const auto & creature : VLC->creh->objects)
{
if(creature->getFaction() == factionIndex && static_cast<int>(creature->getAIValue()) > maxAIValue)
if(creature->getFactionID() == factionIndex && static_cast<int>(creature->getAIValue()) > maxAIValue)
{
maxAIValue = creature->getAIValue();
mostStrong = creature.get();
@ -575,10 +575,10 @@ EBuildingState CGameInfoCallback::canBuildStructure( const CGTownInstance *t, Bu
{
ERROR_RET_VAL_IF(!canGetFullInfo(t), "Town is not owned!", EBuildingState::TOWN_NOT_OWNED);
if(!t->town->buildings.count(ID))
if(!t->getTown()->buildings.count(ID))
return EBuildingState::BUILDING_ERROR;
const CBuilding * building = t->town->buildings.at(ID);
const CBuilding * building = t->getTown()->buildings.at(ID);
if(t->hasBuilt(ID)) //already built

View File

@ -416,9 +416,9 @@ int32_t CUnitState::creatureIconIndex() const
return unitType()->getIconIndex();
}
FactionID CUnitState::getFaction() const
FactionID CUnitState::getFactionID() const
{
return unitType()->getFaction();
return unitType()->getFactionID();
}
int32_t CUnitState::getCasterUnitId() const

View File

@ -253,7 +253,7 @@ public:
void localInit(const IUnitEnvironment * env_);
void serializeJson(JsonSerializeFormat & handler);
FactionID getFaction() const override;
FactionID getFactionID() const override;
void afterAttack(bool ranged, bool counter);

View File

@ -300,15 +300,15 @@ ILimiter::EDecision FactionLimiter::limit(const BonusLimitationContext &context)
if(bearer)
{
if(faction != FactionID::DEFAULT)
return bearer->getFaction() == faction ? ILimiter::EDecision::ACCEPT : ILimiter::EDecision::DISCARD;
return bearer->getFactionID() == faction ? ILimiter::EDecision::ACCEPT : ILimiter::EDecision::DISCARD;
switch(context.b.source)
{
case BonusSource::CREATURE_ABILITY:
return bearer->getFaction() == context.b.sid.as<CreatureID>().toCreature()->getFaction() ? ILimiter::EDecision::ACCEPT : ILimiter::EDecision::DISCARD;
return bearer->getFactionID() == context.b.sid.as<CreatureID>().toCreature()->getFactionID() ? ILimiter::EDecision::ACCEPT : ILimiter::EDecision::DISCARD;
case BonusSource::TOWN_STRUCTURE:
return bearer->getFaction() == context.b.sid.as<BuildingTypeUniqueID>().getFaction() ? ILimiter::EDecision::ACCEPT : ILimiter::EDecision::DISCARD;
return bearer->getFactionID() == context.b.sid.as<BuildingTypeUniqueID>().getFaction() ? ILimiter::EDecision::ACCEPT : ILimiter::EDecision::DISCARD;
//TODO: other sources of bonuses
}

View File

@ -351,14 +351,14 @@ void CampaignState::setCurrentMapAsConquered(std::vector<CGHeroInstance *> heroe
{
JsonNode node = CampaignState::crossoverSerialize(hero);
if (reservedHeroes.count(hero->getHeroType()))
if (reservedHeroes.count(hero->getHeroTypeID()))
{
logGlobal->info("Hero crossover: %d (%s) exported to global pool", hero->getHeroType(), hero->getNameTranslated());
globalHeroPool[hero->getHeroType()] = node;
logGlobal->info("Hero crossover: %d (%s) exported to global pool", hero->getHeroTypeID(), hero->getNameTranslated());
globalHeroPool[hero->getHeroTypeID()] = node;
}
else
{
logGlobal->info("Hero crossover: %d (%s) exported to scenario pool", hero->getHeroType(), hero->getNameTranslated());
logGlobal->info("Hero crossover: %d (%s) exported to scenario pool", hero->getHeroTypeID(), hero->getNameTranslated());
scenarioHeroPool[*currentMap].push_back(node);
}
}

View File

@ -92,7 +92,7 @@ FactionID CFaction::getId() const
return FactionID(index);
}
FactionID CFaction::getFaction() const
FactionID CFaction::getFactionID() const
{
return FactionID(index);
}

View File

@ -39,7 +39,7 @@ class DLL_LINKAGE CFaction : public Faction
FactionID index = FactionID::NEUTRAL;
FactionID getFaction() const override; //This function should not be used
FactionID getFactionID() const override; //This function should not be used
public:
TerrainId nativeTerrain;

View File

@ -599,7 +599,7 @@ void CGameState::initHeroes()
}
hero->initHero(getRandomGenerator());
map->allHeroes[hero->getHeroType().getNum()] = hero;
map->allHeroes[hero->getHeroTypeID().getNum()] = hero;
}
// generate boats for all heroes on water
@ -629,20 +629,20 @@ void CGameState::initHeroes()
{
auto * hero = dynamic_cast<CGHeroInstance*>(obj.get());
hero->initHero(getRandomGenerator());
map->allHeroes[hero->getHeroType().getNum()] = hero;
map->allHeroes[hero->getHeroTypeID().getNum()] = hero;
}
}
std::set<HeroTypeID> heroesToCreate = getUnusedAllowedHeroes(); //ids of heroes to be created and put into the pool
for(auto ph : map->predefinedHeroes)
{
if(!vstd::contains(heroesToCreate, ph->getHeroType()))
if(!vstd::contains(heroesToCreate, ph->getHeroTypeID()))
continue;
ph->initHero(getRandomGenerator());
heroesPool->addHeroToPool(ph);
heroesToCreate.erase(ph->type->getId());
heroesToCreate.erase(ph->getHeroTypeID());
map->allHeroes[ph->getHeroType().getNum()] = ph;
map->allHeroes[ph->getHeroTypeID().getNum()] = ph;
}
for(const HeroTypeID & htype : heroesToCreate) //all not used allowed heroes go with default state into the pool
@ -756,12 +756,12 @@ void CGameState::initTownNames()
for(auto & vti : map->towns)
{
assert(vti->town);
assert(vti->getTown());
if(!vti->getNameTextID().empty())
continue;
FactionID faction = vti->getFaction();
FactionID faction = vti->getFactionID();
if(availableNames.empty())
{
@ -798,8 +798,8 @@ void CGameState::initTowns()
for (auto & vti : map->towns)
{
assert(vti->town);
assert(vti->town->creatures.size() <= GameConstants::CREATURES_PER_TOWN);
assert(vti->getTown());
assert(vti->getTown()->creatures.size() <= GameConstants::CREATURES_PER_TOWN);
constexpr std::array basicDwellings = { BuildingID::DWELL_FIRST, BuildingID::DWELL_LVL_2, BuildingID::DWELL_LVL_3, BuildingID::DWELL_LVL_4, BuildingID::DWELL_LVL_5, BuildingID::DWELL_LVL_6, BuildingID::DWELL_LVL_7, BuildingID::DWELL_LVL_8 };
constexpr std::array upgradedDwellings = { BuildingID::DWELL_UP_FIRST, BuildingID::DWELL_LVL_2_UP, BuildingID::DWELL_LVL_3_UP, BuildingID::DWELL_LVL_4_UP, BuildingID::DWELL_LVL_5_UP, BuildingID::DWELL_LVL_6_UP, BuildingID::DWELL_LVL_7_UP, BuildingID::DWELL_LVL_8_UP };
@ -828,7 +828,7 @@ void CGameState::initTowns()
vti->addBuilding(BuildingID::VILLAGE_HALL);
//init hordes
for (int i = 0; i < vti->town->creatures.size(); i++)
for (int i = 0; i < vti->getTown()->creatures.size(); i++)
{
if(vti->hasBuilt(hordes[i])) //if we have horde for this level
{
@ -894,7 +894,7 @@ void CGameState::initTowns()
int sel = -1;
for(ui32 ps=0;ps<vti->possibleSpells.size();ps++)
total += vti->possibleSpells[ps].toSpell()->getProbability(vti->getFaction());
total += vti->possibleSpells[ps].toSpell()->getProbability(vti->getFactionID());
if (total == 0) // remaining spells have 0 probability
break;
@ -902,7 +902,7 @@ void CGameState::initTowns()
auto r = getRandomGenerator().nextInt(total - 1);
for(ui32 ps=0; ps<vti->possibleSpells.size();ps++)
{
r -= vti->possibleSpells[ps].toSpell()->getProbability(vti->getFaction());
r -= vti->possibleSpells[ps].toSpell()->getProbability(vti->getFactionID());
if(r<0)
{
sel = ps;
@ -1655,18 +1655,13 @@ std::set<HeroTypeID> CGameState::getUnusedAllowedHeroes(bool alsoIncludeNotAllow
}
for(auto hero : map->heroesOnMap) //heroes instances initialization
{
if(hero->type)
ret -= hero->type->getId();
else
ret -= hero->getHeroType();
}
ret -= hero->getHeroTypeID();
for(auto obj : map->objects) //prisons
{
auto * hero = dynamic_cast<const CGHeroInstance *>(obj.get());
if(hero && hero->ID == Obj::PRISON)
ret -= hero->getHeroType();
ret -= hero->getHeroTypeID();
}
return ret;
@ -1690,7 +1685,7 @@ CGHeroInstance * CGameState::getUsedHero(const HeroTypeID & hid) const
auto * hero = dynamic_cast<CGHeroInstance *>(obj.get());
assert(hero);
if (hero->getHeroType() == hid)
if (hero->getHeroTypeID() == hid)
return hero;
}

View File

@ -86,7 +86,7 @@ void CGameStateCampaign::trimCrossoverHeroesParameters(const CampaignTravel & tr
.And(Selector::subtype()(BonusSubtypeID(g)))
.And(Selector::sourceType()(BonusSource::HERO_BASE_SKILL));
hero.hero->getLocalBonus(sel)->val = hero.hero->type->heroClass->primarySkillInitial[g.getNum()];
hero.hero->getLocalBonus(sel)->val = hero.hero->getHeroClass()->primarySkillInitial[g.getNum()];
}
}
}
@ -96,7 +96,7 @@ void CGameStateCampaign::trimCrossoverHeroesParameters(const CampaignTravel & tr
//trimming sec skills
for(auto & hero : campaignHeroReplacements)
{
hero.hero->secSkills = hero.hero->type->secSkillsInit;
hero.hero->secSkills = hero.hero->getHeroType()->secSkillsInit;
hero.hero->recreateSecondarySkillsBonuses();
}
}
@ -240,7 +240,7 @@ void CGameStateCampaign::placeCampaignHeroes()
for(auto & replacement : campaignHeroReplacements)
if (replacement.heroPlaceholderId.hasValue())
heroesToRemove.insert(replacement.hero->getHeroType());
heroesToRemove.insert(replacement.hero->getHeroTypeID());
for(auto & heroID : heroesToRemove)
{
@ -369,8 +369,8 @@ void CGameStateCampaign::replaceHeroesPlaceholders()
if(heroPlaceholder->tempOwner.isValidPlayer())
heroToPlace->tempOwner = heroPlaceholder->tempOwner;
heroToPlace->setAnchorPos(heroPlaceholder->anchorPos());
heroToPlace->type = heroToPlace->getHeroType().toHeroType();
heroToPlace->appearance = VLC->objtypeh->getHandlerFor(Obj::HERO, heroToPlace->type->heroClass->getIndex())->getTemplates().front();
heroToPlace->setHeroType(heroToPlace->getHeroTypeID());
heroToPlace->appearance = VLC->objtypeh->getHandlerFor(Obj::HERO, heroToPlace->getHeroTypeID())->getTemplates().front();
gameState->map->removeBlockVisTiles(heroPlaceholder, true);
gameState->map->objects[heroPlaceholder->id.getNum()] = nullptr;
@ -563,7 +563,7 @@ void CGameStateCampaign::initHeroes()
{
for (auto & hero : heroes)
{
if (hero->getHeroType().getNum() == chosenBonus->info1)
if (hero->getHeroTypeID().getNum() == chosenBonus->info1)
{
giveCampaignBonusToHero(hero);
break;
@ -662,7 +662,7 @@ void CGameStateCampaign::initTowns()
if(gameState->scenarioOps->campState->formatVCMI())
newBuilding = BuildingID(chosenBonus->info1);
else
newBuilding = CBuildingHandler::campToERMU(chosenBonus->info1, town->getFaction(), town->getBuildings());
newBuilding = CBuildingHandler::campToERMU(chosenBonus->info1, town->getFactionID(), town->getBuildings());
// Build granted building & all prerequisites - e.g. Mages Guild Lvl 3 should also give Mages Guild Lvl 1 & 2
while(true)
@ -675,7 +675,7 @@ void CGameStateCampaign::initTowns()
town->addBuilding(newBuilding);
auto building = town->town->buildings.at(newBuilding);
auto building = town->getTown()->buildings.at(newBuilding);
newBuilding = building->upgrade;
}
break;

View File

@ -381,7 +381,7 @@ float Statistic::getTownBuiltRatio(const PlayerState * ps)
for(const auto & t : ps->getTowns())
{
built += t->getBuildings().size();
for(const auto & b : t->town->buildings)
for(const auto & b : t->getTown()->buildings)
if(!t->forbiddenBuildings.count(b.first))
total += 1;
}

View File

@ -115,7 +115,7 @@ void InfoAboutHero::initFromHero(const CGHeroInstance *h, InfoAboutHero::EInfoLe
initFromArmy(h, detailed);
hclass = h->type->heroClass;
hclass = h->getHeroClass();
name = h->getNameTranslated();
portraitSource = h->getPortraitSource();

View File

@ -25,7 +25,7 @@ std::map<HeroTypeID, CGHeroInstance*> TavernHeroesPool::unusedHeroesFromPool() c
{
std::map<HeroTypeID, CGHeroInstance*> pool = heroesPool;
for(const auto & slot : currentTavern)
pool.erase(slot.hero->getHeroType());
pool.erase(slot.hero->getHeroTypeID());
return pool;
}
@ -34,7 +34,7 @@ TavernSlotRole TavernHeroesPool::getSlotRole(HeroTypeID hero) const
{
for (auto const & slot : currentTavern)
{
if (slot.hero->getHeroType() == hero)
if (slot.hero->getHeroTypeID() == hero)
return slot.role;
}
return TavernSlotRole::NONE;
@ -106,7 +106,7 @@ CGHeroInstance * TavernHeroesPool::takeHeroFromPool(HeroTypeID hero)
heroesPool.erase(hero);
vstd::erase_if(currentTavern, [&](const TavernSlot & entry){
return entry.hero->type->getId() == hero;
return entry.hero->getHeroTypeID() == hero;
});
assert(result);
@ -138,7 +138,7 @@ void TavernHeroesPool::onNewDay()
void TavernHeroesPool::addHeroToPool(CGHeroInstance * hero)
{
heroesPool[hero->getHeroType()] = hero;
heroesPool[hero->getHeroTypeID()] = hero;
}
void TavernHeroesPool::setAvailability(HeroTypeID hero, std::set<PlayerColor> mask)

View File

@ -96,7 +96,6 @@ bool CTownInstanceConstructor::objectFilter(const CGObjectInstance * object, std
void CTownInstanceConstructor::initializeObject(CGTownInstance * obj) const
{
obj->town = faction->town;
obj->tempOwner = PlayerColor::NEUTRAL;
}
@ -144,7 +143,7 @@ bool CHeroInstanceConstructor::objectFilter(const CGObjectInstance * object, std
auto heroTest = [&](const HeroTypeID & id)
{
return hero->type->getId() == id;
return hero->getHeroTypeID() == id;
};
if(filters.count(templ->stringID))
@ -154,11 +153,6 @@ bool CHeroInstanceConstructor::objectFilter(const CGObjectInstance * object, std
return false;
}
void CHeroInstanceConstructor::initializeObject(CGHeroInstance * obj) const
{
obj->type = nullptr; //FIXME: set to valid value. somehow.
}
void CHeroInstanceConstructor::randomizeObject(CGHeroInstance * object, vstd::RNG & rng) const
{

View File

@ -81,7 +81,6 @@ public:
const CHeroClass * heroClass = nullptr;
std::map<std::string, LogicalExpression<HeroTypeID>> filters;
void initializeObject(CGHeroInstance * object) const override;
void randomizeObject(CGHeroInstance * object, vstd::RNG & rng) const override;
void afterLoadFinalization() override;

View File

@ -78,7 +78,7 @@ void CArmedInstance::updateMoraleBonusFromArmy()
const CStackInstance * inst = slot.second;
const auto * creature = inst->getCreatureID().toEntity(VLC);
factions.insert(creature->getFaction());
factions.insert(creature->getFactionID());
// Check for undead flag instead of faction (undead mummies are neutral)
if (!hasUndead)
{

View File

@ -45,7 +45,7 @@ std::string CGCreature::getHoverText(PlayerColor player) const
else
ms.appendLocalString(EMetaText::ARRAY_TXT, quantityTextIndex);
ms.appendRawString(" ");
ms.appendNamePlural(getCreature());
ms.appendNamePlural(getCreatureID());
return ms.toString();
}
@ -57,7 +57,7 @@ std::string CGCreature::getHoverText(const CGHeroInstance * hero) const
MetaString ms;
ms.appendNumber(stacks.begin()->second->count);
ms.appendRawString(" ");
ms.appendName(getCreature(), stacks.begin()->second->count);
ms.appendName(getCreatureID(), stacks.begin()->second->count);
return ms.toString();
}
else
@ -69,11 +69,11 @@ std::string CGCreature::getHoverText(const CGHeroInstance * hero) const
std::string CGCreature::getMonsterLevelText() const
{
std::string monsterLevel = VLC->generaltexth->translate("vcmi.adventureMap.monsterLevel");
bool isRanged = VLC->creatures()->getById(getCreature())->getBonusBearer()->hasBonusOfType(BonusType::SHOOTER);
bool isRanged = getCreature()->getBonusBearer()->hasBonusOfType(BonusType::SHOOTER);
std::string attackTypeKey = isRanged ? "vcmi.adventureMap.monsterRangedType" : "vcmi.adventureMap.monsterMeleeType";
std::string attackType = VLC->generaltexth->translate(attackTypeKey);
boost::replace_first(monsterLevel, "%TOWN", (*VLC->townh)[VLC->creatures()->getById(getCreature())->getFaction()]->getNameTranslated());
boost::replace_first(monsterLevel, "%LEVEL", std::to_string(VLC->creatures()->getById(getCreature())->getLevel()));
boost::replace_first(monsterLevel, "%TOWN", getCreature()->getFactionID().toEntity(VLC)->getNameTranslated());
boost::replace_first(monsterLevel, "%LEVEL", std::to_string(getCreature()->getLevel()));
boost::replace_first(monsterLevel, "%ATTACK_TYPE", attackType);
return monsterLevel;
}
@ -150,7 +150,7 @@ std::string CGCreature::getPopupText(PlayerColor player) const
std::vector<Component> CGCreature::getPopupComponents(PlayerColor player) const
{
return {
Component(ComponentType::CREATURE, getCreature())
Component(ComponentType::CREATURE, getCreatureID())
};
}
@ -182,7 +182,7 @@ void CGCreature::onHeroVisit( const CGHeroInstance * h ) const
BlockingDialog ynd(true,false);
ynd.player = h->tempOwner;
ynd.text.appendLocalString(EMetaText::ADVOB_TXT, 86);
ynd.text.replaceName(getCreature(), getStackCount(SlotID(0)));
ynd.text.replaceName(getCreatureID(), getStackCount(SlotID(0)));
cb->showBlockingDialog(this, &ynd);
break;
}
@ -197,7 +197,7 @@ void CGCreature::onHeroVisit( const CGHeroInstance * h ) const
std::string tmp = VLC->generaltexth->advobtxt[90];
boost::algorithm::replace_first(tmp, "%d", std::to_string(getStackCount(SlotID(0))));
boost::algorithm::replace_first(tmp, "%d", std::to_string(action));
boost::algorithm::replace_first(tmp,"%s",VLC->creatures()->getById(getCreature())->getNamePluralTranslated());
boost::algorithm::replace_first(tmp,"%s",getCreature()->getNamePluralTranslated());
ynd.text.appendRawString(tmp);
cb->showBlockingDialog(this, &ynd);
break;
@ -205,11 +205,16 @@ void CGCreature::onHeroVisit( const CGHeroInstance * h ) const
}
}
CreatureID CGCreature::getCreature() const
CreatureID CGCreature::getCreatureID() const
{
return CreatureID(getObjTypeIndex().getNum());
}
const CCreature * CGCreature::getCreature() const
{
return getCreatureID().toCreature();
}
void CGCreature::pickRandomObject(vstd::RNG & rand)
{
switch(ID.toEnum())
@ -279,7 +284,7 @@ void CGCreature::initObj(vstd::RNG & rand)
stacks[SlotID(0)]->setType(getCreature());
TQuantity &amount = stacks[SlotID(0)]->count;
const Creature * c = VLC->creatures()->getById(getCreature());
const Creature * c = getCreature();
if(amount == 0)
{
amount = rand.nextInt(c->getAdvMapAmountMin(), c->getAdvMapAmountMax());
@ -353,8 +358,8 @@ int CGCreature::takenAction(const CGHeroInstance *h, bool allowJoin) const
for(const auto & elem : h->Slots())
{
bool isOurUpgrade = vstd::contains(getCreature().toCreature()->upgrades, elem.second->getCreatureID());
bool isOurDowngrade = vstd::contains(elem.second->type->upgrades, getCreature());
bool isOurUpgrade = vstd::contains(getCreature()->upgrades, elem.second->getCreatureID());
bool isOurDowngrade = vstd::contains(elem.second->type->upgrades, getCreatureID());
if(isOurUpgrade || isOurDowngrade)
count += elem.second->count;
@ -380,7 +385,7 @@ int CGCreature::takenAction(const CGHeroInstance *h, bool allowJoin) const
if(diplomacy * 2 + sympathy + 1 >= character)
{
int32_t recruitCost = VLC->creatures()->getById(getCreature())->getRecruitCost(EGameResID::GOLD);
int32_t recruitCost = getCreature()->getRecruitCost(EGameResID::GOLD);
int32_t stackCount = getStackCount(SlotID(0));
return recruitCost * stackCount; //join for gold
}
@ -493,7 +498,7 @@ void CGCreature::flee( const CGHeroInstance * h ) const
BlockingDialog ynd(true,false);
ynd.player = h->tempOwner;
ynd.text.appendLocalString(EMetaText::ADVOB_TXT,91);
ynd.text.replaceName(getCreature(), getStackCount(SlotID(0)));
ynd.text.replaceName(getCreatureID(), getStackCount(SlotID(0)));
cb->showBlockingDialog(this, &ynd);
}
@ -513,7 +518,7 @@ void CGCreature::battleFinished(const CGHeroInstance *hero, const BattleResult &
{
//merge stacks into one
TSlots::const_iterator i;
const CCreature * cre = getCreature().toCreature();
const CCreature * cre = getCreature();
for(i = stacks.begin(); i != stacks.end(); i++)
{
if(cre->isMyUpgrade(i->second->type))

View File

@ -49,7 +49,8 @@ public:
void newTurn(vstd::RNG & rand) const override;
void battleFinished(const CGHeroInstance *hero, const BattleResult &result) const override;
void blockingDialogAnswered(const CGHeroInstance *hero, int32_t answer) const override;
CreatureID getCreature() const;
CreatureID getCreatureID() const;
const CCreature * getCreature() const;
//stack formation depends on position,
bool containsUpgradedStack() const;

View File

@ -93,7 +93,7 @@ FactionID CGDwelling::randomizeFaction(vstd::RNG & rand)
assert(linkedTown->ID == Obj::TOWN);
if(linkedTown->ID==Obj::TOWN)
return linkedTown->getFaction();
return linkedTown->getFactionID();
}
if(!randomizationInfo->allowedFactions.empty())

View File

@ -116,9 +116,9 @@ ui32 CGHeroInstance::getTileMovementCost(const TerrainTile & dest, const Terrain
return static_cast<ui32>(ret);
}
FactionID CGHeroInstance::getFaction() const
FactionID CGHeroInstance::getFactionID() const
{
return FactionID(type->heroClass->faction);
return getHeroClass()->faction;
}
const IBonusBearer* CGHeroInstance::getBonusBearer() const
@ -229,10 +229,10 @@ bool CGHeroInstance::canLearnSkill(const SecondarySkill & which) const
if (getSecSkillLevel(which) > 0)
return false;
if (type->heroClass->secSkillProbability.count(which) == 0)
if (getHeroClass()->secSkillProbability.count(which) == 0)
return false;
if (type->heroClass->secSkillProbability.at(which) == 0)
if (getHeroClass()->secSkillProbability.at(which) == 0)
return false;
return true;
@ -282,7 +282,6 @@ int CGHeroInstance::movementPointsLimitCached(bool onLand, const TurnInfo * ti)
CGHeroInstance::CGHeroInstance(IGameCallback * cb)
: CArmedInstance(cb),
type(nullptr),
tacticFormationEnabled(false),
inTownGarrison(false),
moveDir(4),
@ -303,14 +302,30 @@ PlayerColor CGHeroInstance::getOwner() const
return tempOwner;
}
HeroTypeID CGHeroInstance::getHeroType() const
const CHeroClass * CGHeroInstance::getHeroClass() const
{
return getHeroType()->heroClass;
}
HeroClassID CGHeroInstance::getHeroClassID() const
{
return getHeroType()->heroClass->getId();
}
const CHero * CGHeroInstance::getHeroType() const
{
return getHeroTypeID().toHeroType();
}
HeroTypeID CGHeroInstance::getHeroTypeID() const
{
if (ID == Obj::RANDOM_HERO)
return HeroTypeID::NONE;
return HeroTypeID(getObjTypeIndex().getNum());
}
void CGHeroInstance::setHeroType(HeroTypeID heroType)
{
assert(type == nullptr);
subID = heroType;
}
@ -323,16 +338,14 @@ void CGHeroInstance::initHero(vstd::RNG & rand, const HeroTypeID & SUBID)
void CGHeroInstance::initHero(vstd::RNG & rand)
{
assert(validTypes(true));
if(!type)
type = getHeroType().toHeroType();
if (ID == Obj::HERO)
appearance = VLC->objtypeh->getHandlerFor(Obj::HERO, type->heroClass->getIndex())->getTemplates().front();
appearance = VLC->objtypeh->getHandlerFor(Obj::HERO, getHeroClass()->getIndex())->getTemplates().front();
if(!vstd::contains(spells, SpellID::PRESET))
{
// hero starts with default spells
for(const auto & spellID : type->spells)
for(const auto & spellID : getHeroType()->spells)
spells.insert(spellID);
}
else //remove placeholder
@ -341,7 +354,7 @@ void CGHeroInstance::initHero(vstd::RNG & rand)
if(!vstd::contains(spells, SpellID::SPELLBOOK_PRESET))
{
// hero starts with default spellbook presence status
if(!getArt(ArtifactPosition::SPELLBOOK) && type->haveSpellBook)
if(!getArt(ArtifactPosition::SPELLBOOK) && getHeroType()->haveSpellBook)
{
auto artifact = ArtifactUtils::createArtifact(ArtifactID::SPELLBOOK);
putArtifact(ArtifactPosition::SPELLBOOK, artifact);
@ -360,14 +373,14 @@ void CGHeroInstance::initHero(vstd::RNG & rand)
{
for(int g=0; g<GameConstants::PRIMARY_SKILLS; ++g)
{
pushPrimSkill(static_cast<PrimarySkill>(g), type->heroClass->primarySkillInitial[g]);
pushPrimSkill(static_cast<PrimarySkill>(g), getHeroClass()->primarySkillInitial[g]);
}
}
if(secSkills.size() == 1 && secSkills[0] == std::pair<SecondarySkill,ui8>(SecondarySkill::NONE, -1)) //set secondary skills to default
secSkills = type->secSkillsInit;
secSkills = getHeroType()->secSkillsInit;
if (gender == EHeroGender::DEFAULT)
gender = type->gender;
gender = getHeroType()->gender;
setFormation(EArmyFormation::LOOSE);
if (!stacksCount()) //standard army//initial army
@ -403,9 +416,9 @@ void CGHeroInstance::initHero(vstd::RNG & rand)
addNewBonus(bonus);
}
if (cb->getSettings().getBoolean(EGameSettings::MODULE_COMMANDERS) && !commander && type->heroClass->commander.hasValue())
if (cb->getSettings().getBoolean(EGameSettings::MODULE_COMMANDERS) && !commander && getHeroClass()->commander.hasValue())
{
commander = new CCommanderInstance(type->heroClass->commander);
commander = new CCommanderInstance(getHeroClass()->commander);
commander->setArmyObj (castToArmyObj()); //TODO: separate function for setting commanders
commander->giveStackExp (exp); //after our exp is set
}
@ -413,7 +426,7 @@ void CGHeroInstance::initHero(vstd::RNG & rand)
skillsInfo = SecondarySkillsInfo();
//copy active (probably growing) bonuses from hero prototype to hero object
for(const std::shared_ptr<Bonus> & b : type->specialty)
for(const std::shared_ptr<Bonus> & b : getHeroType()->specialty)
addNewBonus(b);
//initialize bonuses
@ -433,14 +446,14 @@ void CGHeroInstance::initArmy(vstd::RNG & rand, IArmyDescriptor * dst)
auto stacksCountChances = cb->getSettings().getVector(EGameSettings::HEROES_STARTING_STACKS_CHANCES);
int stacksCountInitRandomNumber = rand.nextInt(1, 100);
size_t maxStacksCount = std::min(stacksCountChances.size(), type->initialArmy.size());
size_t maxStacksCount = std::min(stacksCountChances.size(), getHeroType()->initialArmy.size());
for(int stackNo=0; stackNo < maxStacksCount; stackNo++)
{
if (stacksCountInitRandomNumber > stacksCountChances[stackNo])
continue;
auto & stack = type->initialArmy[stackNo];
auto & stack = getHeroType()->initialArmy[stackNo];
int count = rand.nextInt(stack.minAmount, stack.maxAmount);
@ -588,11 +601,11 @@ std::string CGHeroInstance::getMovementPointsTextIfOwner(PlayerColor player) con
ui8 CGHeroInstance::maxlevelsToMagicSchool() const
{
return type->heroClass->isMagicHero() ? 3 : 4;
return getHeroClass()->isMagicHero() ? 3 : 4;
}
ui8 CGHeroInstance::maxlevelsToWisdom() const
{
return type->heroClass->isMagicHero() ? 3 : 6;
return getHeroClass()->isMagicHero() ? 3 : 6;
}
CGHeroInstance::SecondarySkillsInfo::SecondarySkillsInfo():
@ -617,11 +630,8 @@ void CGHeroInstance::pickRandomObject(vstd::RNG & rand)
{
ID = Obj::HERO;
subID = cb->gameState()->pickNextHeroType(getOwner());
type = getHeroType().toHeroType();
randomizeArmy(type->heroClass->faction);
randomizeArmy(getHeroClass()->faction);
}
else
type = getHeroType().toHeroType();
auto oldSubID = subID;
@ -629,7 +639,7 @@ void CGHeroInstance::pickRandomObject(vstd::RNG & rand)
// after setType subID used to store unique hero identify id. Check issue 2277 for details
// exclude prisons which should use appearance as set in map, via map editor or RMG
if (ID != Obj::PRISON)
setType(ID, type->heroClass->getIndex());
setType(ID, getHeroClass()->getIndex());
this->subID = oldSubID;
}
@ -1041,7 +1051,7 @@ si32 CGHeroInstance::getManaNewTurn() const
BoatId CGHeroInstance::getBoatType() const
{
return BoatId(VLC->townh->getById(type->heroClass->faction)->getBoatType());
return BoatId(VLC->townh->getById(getHeroClass()->faction)->getBoatType());
}
void CGHeroInstance::getOutOffsets(std::vector<int3> &offsets) const
@ -1080,7 +1090,7 @@ void CGHeroInstance::pushPrimSkill( PrimarySkill which, int val )
EAlignment CGHeroInstance::getAlignment() const
{
return type->heroClass->getAlignment();
return getHeroClass()->getAlignment();
}
void CGHeroInstance::initExp(vstd::RNG & rand)
@ -1104,12 +1114,12 @@ HeroTypeID CGHeroInstance::getPortraitSource() const
if (customPortraitSource.isValid())
return customPortraitSource;
else
return getHeroType();
return getHeroTypeID();
}
int32_t CGHeroInstance::getIconIndex() const
{
return VLC->heroTypes()->getById(getPortraitSource())->getIconIndex();
return getPortraitSource().toEntity(VLC)->getIconIndex();
}
std::string CGHeroInstance::getNameTranslated() const
@ -1126,15 +1136,15 @@ std::string CGHeroInstance::getClassNameTextID() const
{
if (isCampaignGem())
return "core.genrltxt.735";
return type->heroClass->getNameTextID();
return getHeroClass()->getNameTextID();
}
std::string CGHeroInstance::getNameTextID() const
{
if (!nameCustomTextId.empty())
return nameCustomTextId;
if (type)
return type->getNameTextID();
if (getHeroTypeID().hasValue())
return getHeroType()->getNameTextID();
// FIXME: called by logging from some specialties (mods?) before type is set on deserialization
// assert(0);
@ -1150,8 +1160,8 @@ std::string CGHeroInstance::getBiographyTextID() const
{
if (!biographyCustomTextId.empty())
return biographyCustomTextId;
if (type)
return type->getBiographyTextID();
if (getHeroTypeID().hasValue())
return getHeroType()->getBiographyTextID();
return ""; //for random hero
}
@ -1349,11 +1359,11 @@ std::vector<SecondarySkill> CGHeroInstance::getLevelUpProposedSecondarySkills(vs
SecondarySkill selection;
if (selectWisdom)
selection = type->heroClass->chooseSecSkill(intersect(options, wisdomList), rand);
selection = getHeroClass()->chooseSecSkill(intersect(options, wisdomList), rand);
else if (selectSchool)
selection = type->heroClass->chooseSecSkill(intersect(options, schoolList), rand);
selection = getHeroClass()->chooseSecSkill(intersect(options, schoolList), rand);
else
selection = type->heroClass->chooseSecSkill(options, rand);
selection = getHeroClass()->chooseSecSkill(options, rand);
skills.push_back(selection);
options.erase(selection);
@ -1384,7 +1394,7 @@ PrimarySkill CGHeroInstance::nextPrimarySkill(vstd::RNG & rand) const
{
assert(gainsLevel());
const auto isLowLevelHero = level < GameConstants::HERO_HIGH_LEVEL;
const auto & skillChances = isLowLevelHero ? type->heroClass->primarySkillLowLevel : type->heroClass->primarySkillHighLevel;
const auto & skillChances = isLowLevelHero ? getHeroClass()->primarySkillLowLevel : getHeroClass()->primarySkillHighLevel;
if (isCampaignYog())
{
@ -1524,25 +1534,15 @@ bool CGHeroInstance::hasVisions(const CGObjectInstance * target, BonusSubtypeID
std::string CGHeroInstance::getHeroTypeName() const
{
if(ID == Obj::HERO || ID == Obj::PRISON)
{
if(type)
{
return type->getJsonKey();
}
else
{
return getHeroType().toEntity(VLC)->getJsonKey();
}
}
return getHeroType()->getJsonKey();
return "";
}
void CGHeroInstance::afterAddToMap(CMap * map)
{
if(ID != Obj::PRISON)
{
map->heroesOnMap.emplace_back(this);
}
}
void CGHeroInstance::afterRemoveFromMap(CMap* map)
{
@ -1729,8 +1729,7 @@ void CGHeroInstance::serializeJsonOptions(JsonSerializeFormat & handler)
if(!appearance)
{
// crossoverDeserialize
type = getHeroType().toHeroType();
appearance = VLC->objtypeh->getHandlerFor(Obj::HERO, type->heroClass->getIndex())->getTemplates().front();
appearance = VLC->objtypeh->getHandlerFor(Obj::HERO, getHeroClassID())->getTemplates().front();
}
}
@ -1817,7 +1816,7 @@ bool CGHeroInstance::isCampaignYog() const
if (!boost::starts_with(campaign, "DATA/YOG")) // "Birth of a Barbarian"
return false;
if (getHeroType() != HeroTypeID::SOLMYR) // Yog (based on Solmyr)
if (getHeroTypeID() != HeroTypeID::SOLMYR) // Yog (based on Solmyr)
return false;
return true;
@ -1835,7 +1834,7 @@ bool CGHeroInstance::isCampaignGem() const
if (!boost::starts_with(campaign, "DATA/GEM") && !boost::starts_with(campaign, "DATA/FINAL")) // "New Beginning" and "Unholy Alliance"
return false;
if (getHeroType() != HeroTypeID::GEM) // Yog (based on Solmyr)
if (getHeroTypeID() != HeroTypeID::GEM) // Yog (based on Solmyr)
return false;
return true;

View File

@ -72,7 +72,6 @@ public:
//////////////////////////////////////////////////////////////////////////
const CHero * type;
TExpType exp; //experience points
ui32 level; //current level of hero
@ -171,7 +170,7 @@ public:
const IOwnableObject * asOwnable() const final;
//INativeTerrainProvider
FactionID getFaction() const override;
FactionID getFactionID() const override;
TerrainId getNativeTerrain() const override;
int getLowestCreatureSpeed() const;
si32 manaRegain() const; //how many points of mana can hero regain "naturally" in one day
@ -235,7 +234,11 @@ public:
//////////////////////////////////////////////////////////////////////////
HeroTypeID getHeroType() const;
const CHeroClass * getHeroClass() const;
HeroClassID getHeroClassID() const;
const CHero * getHeroType() const;
HeroTypeID getHeroTypeID() const;
void setHeroType(HeroTypeID type);
void initHero(vstd::RNG & rand);
@ -352,7 +355,11 @@ public:
h & skillsInfo;
h & visitedTown;
h & boat;
h & type;
if (h.version < Handler::Version::REMOVE_TOWN_PTR)
{
CHero * type = nullptr;
h & type;
}
h & commander;
h & visitedObjects;
BONUS_TREE_DESERIALIZATION_FIX

View File

@ -45,7 +45,7 @@ int CGTownInstance::getSightRadius() const //returns sight distance
for(const auto & bid : builtBuildings)
{
auto height = town->buildings.at(bid)->height;
auto height = getTown()->buildings.at(bid)->height;
if(ret < height)
ret = height;
}
@ -115,7 +115,7 @@ int CGTownInstance::mageGuildLevel() const
int CGTownInstance::getHordeLevel(const int & HID) const//HID - 0 or 1; returns creature level or -1 if that horde structure is not present
{
return town->hordeLvl.at(HID);
return getTown()->hordeLvl.at(HID);
}
int CGTownInstance::creatureGrowth(const int & level) const
@ -127,7 +127,7 @@ GrowthInfo CGTownInstance::getGrowthInfo(int level) const
{
GrowthInfo ret;
if (level<0 || level >=town->creatures.size())
if (level<0 || level >=getTown()->creatures.size())
return ret;
if (creatures[level].second.empty())
return ret; //no dwelling
@ -151,11 +151,11 @@ GrowthInfo CGTownInstance::getGrowthInfo(int level) const
else if (hasBuilt(BuildingID::CITADEL))
ret.entries.emplace_back(subID, BuildingID::CITADEL, castleBonus = base / 2);
if(town->hordeLvl.at(0) == level)//horde 1
if(getTown()->hordeLvl.at(0) == level)//horde 1
if(hasBuilt(BuildingID::HORDE_1))
ret.entries.emplace_back(subID, BuildingID::HORDE_1, creature->getHorde());
if(town->hordeLvl.at(1) == level)//horde 2
if(getTown()->hordeLvl.at(1) == level)//horde 2
if(hasBuilt(BuildingID::HORDE_2))
ret.entries.emplace_back(subID, BuildingID::HORDE_2, creature->getHorde());
@ -209,11 +209,11 @@ int CGTownInstance::getDwellingBonus(const std::vector<CreatureID>& creatureIds,
TResources CGTownInstance::dailyIncome() const
{
TResources ret;
for(const auto & p : town->buildings)
for(const auto & p : getTown()->buildings)
{
BuildingID buildingUpgrade;
for(const auto & p2 : town->buildings)
for(const auto & p2 : getTown()->buildings)
{
if (p2.second->upgrade == p.first)
{
@ -251,10 +251,10 @@ bool CGTownInstance::hasCapitol() const
TownFortifications CGTownInstance::fortificationsLevel() const
{
auto result = town->fortifications;
auto result = getTown()->fortifications;
for (auto const & buildingID : builtBuildings)
result += town->buildings.at(buildingID)->fortifications;
result += getTown()->buildings.at(buildingID)->fortifications;
if (result.wallsHealth == 0)
return TownFortifications();
@ -264,7 +264,6 @@ TownFortifications CGTownInstance::fortificationsLevel() const
CGTownInstance::CGTownInstance(IGameCallback *cb):
CGDwelling(cb),
town(nullptr),
built(0),
destroyed(0),
identifier(0),
@ -379,17 +378,17 @@ void CGTownInstance::onHeroLeave(const CGHeroInstance * h) const
std::string CGTownInstance::getObjectName() const
{
return getNameTranslated() + ", " + town->faction->getNameTranslated();
return getNameTranslated() + ", " + getTown()->faction->getNameTranslated();
}
bool CGTownInstance::townEnvisagesBuilding(BuildingSubID::EBuildingSubID subId) const
{
return town->getBuildingType(subId) != BuildingID::NONE;
return getTown()->getBuildingType(subId) != BuildingID::NONE;
}
void CGTownInstance::initializeConfigurableBuildings(vstd::RNG & rand)
{
for(const auto & kvp : town->buildings)
for(const auto & kvp : getTown()->buildings)
{
if(!kvp.second->rewardableObjectInfo.getParameters().isNull())
rewardableBuildings[kvp.first] = new TownRewardableBuildingInstance(this, kvp.second->bid, rand);
@ -457,8 +456,7 @@ void CGTownInstance::pickRandomObject(vstd::RNG & rand)
assert(ID == Obj::TOWN); // just in case
setType(ID, subID);
town = (*VLC->townh)[getFaction()]->town;
randomizeArmy(getFaction());
randomizeArmy(getFactionID());
updateAppearance();
}
@ -467,19 +465,19 @@ void CGTownInstance::initObj(vstd::RNG & rand) ///initialize town structures
blockVisit = true;
if(townEnvisagesBuilding(BuildingSubID::PORTAL_OF_SUMMONING)) //Dungeon for example
creatures.resize(town->creatures.size() + 1);
creatures.resize(getTown()->creatures.size() + 1);
else
creatures.resize(town->creatures.size());
creatures.resize(getTown()->creatures.size());
for (int level = 0; level < town->creatures.size(); level++)
for (int level = 0; level < getTown()->creatures.size(); level++)
{
BuildingID buildID = BuildingID(BuildingID::getDwellingFromLevel(level, 0));
int upgradeNum = 0;
for (; town->buildings.count(buildID); upgradeNum++, BuildingID::advanceDwelling(buildID))
for (; getTown()->buildings.count(buildID); upgradeNum++, BuildingID::advanceDwelling(buildID))
{
if (hasBuilt(buildID) && town->creatures.at(level).size() > upgradeNum)
creatures[level].second.push_back(town->creatures[level][upgradeNum]);
if (hasBuilt(buildID) && getTown()->creatures.at(level).size() > upgradeNum)
creatures[level].second.push_back(getTown()->creatures[level][upgradeNum]);
}
}
initializeConfigurableBuildings(rand);
@ -623,9 +621,9 @@ void CGTownInstance::removeCapitols(const PlayerColor & owner) const
if (hasCapitol()) // search if there's an older capitol
{
PlayerState* state = cb->gameState()->getPlayerState(owner); //get all towns owned by player
for (const auto & town : state->getTowns())
for (const auto & otherTown : state->getTowns())
{
if (town != this && town->hasCapitol())
if (otherTown != this && otherTown->hasCapitol())
{
RazeStructures rs;
rs.tid = id;
@ -648,7 +646,7 @@ void CGTownInstance::clearArmy() const
BoatId CGTownInstance::getBoatType() const
{
return town->faction->boatType;
return getTown()->faction->boatType;
}
int CGTownInstance::getMarketEfficiency() const
@ -703,7 +701,7 @@ void CGTownInstance::updateAppearance()
std::string CGTownInstance::nodeName() const
{
return "Town (" + (town ? town->faction->getNameTranslated() : "unknown") + ") of " + getNameTranslated();
return "Town (" + getTown()->faction->getNameTranslated() + ") of " + getNameTranslated();
}
void CGTownInstance::deserializationFix()
@ -752,7 +750,7 @@ void CGTownInstance::recreateBuildingsBonuses()
for(const auto & upgradeID : builtBuildings)
{
const auto & upgrade = town->buildings.at(upgradeID);
const auto & upgrade = getTown()->buildings.at(upgradeID);
if (upgrade->getBase() == bid && upgrade->upgradeReplacesBonuses)
bonusesReplacedByUpgrade = true;
}
@ -761,7 +759,7 @@ void CGTownInstance::recreateBuildingsBonuses()
if (bonusesReplacedByUpgrade)
continue;
auto building = town->buildings.at(bid);
auto building = getTown()->buildings.at(bid);
if(building->buildingBonuses.empty())
continue;
@ -828,21 +826,6 @@ bool CGTownInstance::armedGarrison() const
return !stacks.empty() || garrisonHero;
}
const CTown * CGTownInstance::getTown() const
{
if(ID == Obj::RANDOM_TOWN)
return VLC->townh->randomTown;
else
{
if(nullptr == town)
{
return (*VLC->townh)[getFaction()]->town;
}
else
return town;
}
}
int CGTownInstance::getTownLevel() const
{
// count all buildings that are not upgrades
@ -850,7 +833,7 @@ int CGTownInstance::getTownLevel() const
for(const auto & bid : builtBuildings)
{
if(town->buildings.at(bid)->upgrade == BuildingID::NONE)
if(getTown()->buildings.at(bid)->upgrade == BuildingID::NONE)
level++;
}
return level;
@ -892,7 +875,7 @@ bool CGTownInstance::hasBuilt(BuildingSubID::EBuildingSubID buildingID) const
{
for(const auto & bid : builtBuildings)
{
if(town->buildings.at(bid)->subId == buildingID)
if(getTown()->buildings.at(bid)->subId == buildingID)
return true;
}
return false;
@ -905,7 +888,7 @@ bool CGTownInstance::hasBuilt(const BuildingID & buildingID) const
bool CGTownInstance::hasBuilt(const BuildingID & buildingID, FactionID townID) const
{
if (townID == town->faction->getId() || townID == FactionID::ANY)
if (townID == getTown()->faction->getId() || townID == FactionID::ANY)
return hasBuilt(buildingID);
return false;
}
@ -923,7 +906,7 @@ std::set<EMarketMode> CGTownInstance::availableModes() const
std::set<EMarketMode> result;
for (const auto & buildingID : builtBuildings)
{
const auto * buildingPtr = town->buildings.at(buildingID).get();
const auto * buildingPtr = getTown()->buildings.at(buildingID).get();
result.insert(buildingPtr->marketModes.begin(), buildingPtr->marketModes.end());
}
@ -950,8 +933,8 @@ std::set<BuildingID> CGTownInstance::getBuildings() const
TResources CGTownInstance::getBuildingCost(const BuildingID & buildingID) const
{
if (vstd::contains(town->buildings, buildingID))
return town->buildings.at(buildingID)->resources;
if (vstd::contains(getTown()->buildings, buildingID))
return getTown()->buildings.at(buildingID)->resources;
else
{
logGlobal->error("Town %s at %s has no possible building %d!", getNameTranslated(), anchorPos().toString(), buildingID.toEnum());
@ -962,7 +945,7 @@ TResources CGTownInstance::getBuildingCost(const BuildingID & buildingID) const
CBuilding::TRequired CGTownInstance::genBuildingRequirements(const BuildingID & buildID, bool deep) const
{
const CBuilding * building = town->buildings.at(buildID);
const CBuilding * building = getTown()->buildings.at(buildID);
//TODO: find better solution to prevent infinite loops
std::set<BuildingID> processed;
@ -970,13 +953,13 @@ CBuilding::TRequired CGTownInstance::genBuildingRequirements(const BuildingID &
std::function<CBuilding::TRequired::Variant(const BuildingID &)> dependTest =
[&](const BuildingID & id) -> CBuilding::TRequired::Variant
{
if (town->buildings.count(id) == 0)
if (getTown()->buildings.count(id) == 0)
{
logMod->error("Invalid building ID %d in building dependencies!", id.getNum());
return CBuilding::TRequired::OperatorAll();
}
const CBuilding * build = town->buildings.at(id);
const CBuilding * build = getTown()->buildings.at(id);
CBuilding::TRequired::OperatorAll requirements;
if (!hasBuilt(id))
@ -1001,7 +984,7 @@ CBuilding::TRequired CGTownInstance::genBuildingRequirements(const BuildingID &
CBuilding::TRequired::OperatorAll requirements;
if (building->upgrade != BuildingID::NONE)
{
const CBuilding * upgr = town->buildings.at(building->upgrade);
const CBuilding * upgr = getTown()->buildings.at(building->upgrade);
requirements.expressions.push_back(dependTest(upgr->bid));
processed.clear();
@ -1151,14 +1134,27 @@ void CGTownInstance::serializeJsonOptions(JsonSerializeFormat & handler)
}
}
FactionID CGTownInstance::getFaction() const
const CFaction * CGTownInstance::getFaction() const
{
return FactionID(subID.getNum());
return getFactionID().toFaction();
}
const CTown * CGTownInstance::getTown() const
{
if(ID == Obj::RANDOM_TOWN)
return VLC->townh->randomTown;
return getFaction()->town;
}
FactionID CGTownInstance::getFactionID() const
{
return FactionID(subID.getNum());
}
TerrainId CGTownInstance::getNativeTerrain() const
{
return town->faction->getNativeTerrain();
return getTown()->faction->getNativeTerrain();
}
ArtifactID CGTownInstance::getWarMachineInBuilding(BuildingID building) const
@ -1166,21 +1162,21 @@ ArtifactID CGTownInstance::getWarMachineInBuilding(BuildingID building) const
if (builtBuildings.count(building) == 0)
return ArtifactID::NONE;
if (building == BuildingID::BLACKSMITH && town->warMachineDeprecated.hasValue())
return town->warMachineDeprecated.toCreature()->warMachine;
if (building == BuildingID::BLACKSMITH && getTown()->warMachineDeprecated.hasValue())
return getTown()->warMachineDeprecated.toCreature()->warMachine;
return town->buildings.at(building)->warMachine;
return getTown()->buildings.at(building)->warMachine;
}
bool CGTownInstance::isWarMachineAvailable(ArtifactID warMachine) const
{
for (auto const & buildingID : builtBuildings)
if (town->buildings.at(buildingID)->warMachine == warMachine)
if (getTown()->buildings.at(buildingID)->warMachine == warMachine)
return true;
if (builtBuildings.count(BuildingID::BLACKSMITH) &&
town->warMachineDeprecated.hasValue() &&
town->warMachineDeprecated.toCreature()->warMachine == warMachine)
getTown()->warMachineDeprecated.hasValue() &&
getTown()->warMachineDeprecated.toCreature()->warMachine == warMachine)
return true;
return false;
@ -1200,7 +1196,7 @@ GrowthInfo::Entry::Entry(int subID, const BuildingID & building, int _count): co
{
MetaString formatter;
formatter.appendRawString("%s %+d");
formatter.replaceRawString((*VLC->townh)[subID]->town->buildings.at(building)->getNameTranslated());
formatter.replaceRawString(FactionID(subID).toFaction()->town->buildings.at(building)->getNameTranslated());
formatter.replacePositiveNumber(count);
description = formatter.toString();

View File

@ -50,6 +50,7 @@ struct DLL_LINKAGE GrowthInfo
class DLL_LINKAGE CGTownInstance : public CGDwelling, public IShipyard, public IMarket, public INativeTerrainProvider, public ICreatureUpgrader
{
friend class CTownInstanceConstructor;
std::string nameTextId; // name of town
std::map<BuildingID, TownRewardableBuildingInstance*> convertOldBuildings(std::vector<TownRewardableBuildingInstance*> oldVector);
@ -59,7 +60,6 @@ public:
enum EFortLevel {NONE = 0, FORT = 1, CITADEL = 2, CASTLE = 3};
CTownAndVisitingHero townAndVis;
const CTown * town;
si32 built; //how many buildings has been built this turn
si32 destroyed; //how many buildings has been destroyed this turn
ConstTransitivePtr<CGHeroInstance> garrisonHero, visitingHero;
@ -112,16 +112,21 @@ public:
rewardableBuildings = convertOldBuildings(oldVector);
}
if (h.saving)
if (h.version < Handler::Version::REMOVE_TOWN_PTR)
{
CFaction * faction = town ? town->faction : nullptr;
h & faction;
}
else
{
CFaction * faction = nullptr;
h & faction;
town = faction ? faction->town : nullptr;
CTown * town = nullptr;
if (h.saving)
{
CFaction * faction = town ? town->faction : nullptr;
h & faction;
}
else
{
CFaction * faction = nullptr;
h & faction;
town = faction ? faction->town : nullptr;
}
}
h & townAndVis;
@ -213,9 +218,10 @@ public:
DamageRange getKeepDamageRange() const;
const CTown * getTown() const;
const CFaction * getFaction() const;
/// INativeTerrainProvider
FactionID getFaction() const override;
FactionID getFactionID() const override;
TerrainId getNativeTerrain() const override;
/// Returns ID of war machine that is produced by specified building or NONE if this is not built or if building does not produce war machines

View File

@ -431,7 +431,7 @@ void CGSeerHut::setObjToKill()
if(getCreatureToKill(true))
{
quest->stackToKill = getCreatureToKill(false)->getCreature();
quest->stackToKill = getCreatureToKill(false)->getCreatureID();
assert(quest->stackToKill != CreatureID::NONE);
quest->stackDirection = checkDirection();
}

View File

@ -73,14 +73,14 @@ TownRewardableBuildingInstance::TownRewardableBuildingInstance(CGTownInstance *
void TownRewardableBuildingInstance::initObj(vstd::RNG & rand)
{
assert(town && town->town);
assert(town && town->getTown());
configuration = generateConfiguration(rand);
}
Rewardable::Configuration TownRewardableBuildingInstance::generateConfiguration(vstd::RNG & rand) const
{
Rewardable::Configuration result;
auto building = town->town->buildings.at(getBuildingType());
auto building = town->getTown()->buildings.at(getBuildingType());
building->rewardableObjectInfo.configureObject(result, rand, cb);
for(auto & rewardInfo : result.info)

View File

@ -302,7 +302,7 @@ void CMap::calculateGuardingGreaturePositions()
CGHeroInstance * CMap::getHero(HeroTypeID heroID)
{
for(auto & elem : heroesOnMap)
if(elem->getHeroType() == heroID)
if(elem->getHeroTypeID() == heroID)
return elem;
return nullptr;
}

View File

@ -896,7 +896,7 @@ void CMapLoaderH3M::readPredefinedHeroes()
}
map->predefinedHeroes.emplace_back(hero);
logGlobal->debug("Map '%s': Hero predefined in map: %s", mapName, VLC->heroh->getById(hero->getHeroType())->getJsonKey());
logGlobal->debug("Map '%s': Hero predefined in map: %s", mapName, hero->getHeroType()->getJsonKey());
}
}
@ -913,7 +913,7 @@ void CMapLoaderH3M::loadArtifactsOfHero(CGHeroInstance * hero)
if(!hero->artifactsWorn.empty() || !hero->artifactsInBackpack.empty())
{
logGlobal->debug("Hero %d at %s has set artifacts twice (in map properties and on adventure map instance). Using the latter set...", hero->getHeroType().getNum(), hero->anchorPos().toString());
logGlobal->debug("Hero %d at %s has set artifacts twice (in map properties and on adventure map instance). Using the latter set...", hero->getHeroTypeID().getNum(), hero->anchorPos().toString());
hero->artifactsInBackpack.clear();
while(!hero->artifactsWorn.empty())
@ -1778,7 +1778,7 @@ CGObjectInstance * CMapLoaderH3M::readHero(const int3 & mapPosition, const Objec
for(auto & elem : map->disposedHeroes)
{
if(elem.heroId == object->getHeroType())
if(elem.heroId == object->getHeroTypeID())
{
object->nameCustomTextId = elem.name;
object->customPortraitSource = elem.portrait;
@ -1788,7 +1788,7 @@ CGObjectInstance * CMapLoaderH3M::readHero(const int3 & mapPosition, const Objec
bool hasName = reader->readBool();
if(hasName)
object->nameCustomTextId = readLocalizedString(TextIdentifier("heroes", object->getHeroType().getNum(), "name"));
object->nameCustomTextId = readLocalizedString(TextIdentifier("heroes", object->getHeroTypeID().getNum(), "name"));
if(features.levelSOD)
{
@ -1891,7 +1891,7 @@ CGObjectInstance * CMapLoaderH3M::readHero(const int3 & mapPosition, const Objec
auto ps = object->getAllBonuses(Selector::type()(BonusType::PRIMARY_SKILL).And(Selector::sourceType()(BonusSource::HERO_BASE_SKILL)), nullptr);
if(ps->size())
{
logGlobal->debug("Hero %s has set primary skills twice (in map properties and on adventure map instance). Using the latter set...", object->getHeroType().getNum() );
logGlobal->debug("Hero %s has set primary skills twice (in map properties and on adventure map instance). Using the latter set...", object->getHeroTypeID().getNum() );
for(const auto & b : *ps)
object->removeBonus(b);
}
@ -1904,7 +1904,7 @@ CGObjectInstance * CMapLoaderH3M::readHero(const int3 & mapPosition, const Objec
}
if (object->subID != MapObjectSubID())
logGlobal->debug("Map '%s': Hero on map: %s at %s, owned by %s", mapName, VLC->heroh->getById(object->getHeroType())->getJsonKey(), mapPosition.toString(), object->getOwner().toString());
logGlobal->debug("Map '%s': Hero on map: %s at %s, owned by %s", mapName, object->getHeroType()->getJsonKey(), mapPosition.toString(), object->getOwner().toString());
else
logGlobal->debug("Map '%s': Hero on map: (random) at %s, owned by %s", mapName, mapPosition.toString(), object->getOwner().toString());

View File

@ -436,10 +436,8 @@ void CMapFormatJson::serializePlayerInfo(JsonSerializeFormat & handler)
if(hero->ID == Obj::HERO)
{
std::string temp;
if(hero->type)
temp = hero->type->getJsonKey();
else
temp = hero->getHeroType().toEntity(VLC)->getJsonKey();
if(hero->getHeroTypeID().hasValue())
temp = hero->getHeroType()->getJsonKey();
handler.serializeString("type", temp);
}
@ -1154,10 +1152,10 @@ void CMapLoaderJson::readObjects()
auto * hero = dynamic_cast<const CGHeroInstance *>(object.get());
if (debugHeroesOnMap.count(hero->getHeroType()))
if (debugHeroesOnMap.count(hero->getHeroTypeID()))
logGlobal->error("Hero is already on the map at %s", hero->visitablePos().toString());
debugHeroesOnMap.insert(hero->getHeroType());
debugHeroesOnMap.insert(hero->getHeroTypeID());
}
}

View File

@ -1355,7 +1355,7 @@ void NewStructures::applyGs(CGameState *gs)
for(const auto & id : bid)
{
assert(t->town->buildings.at(id) != nullptr);
assert(t->getTown()->buildings.at(id) != nullptr);
t->addBuilding(id);
}
t->updateAppearance();
@ -1470,7 +1470,7 @@ void GiveHero::applyGs(CGameState *gs)
auto oldVisitablePos = h->visitablePos();
gs->map->removeBlockVisTiles(h,true);
h->appearance = VLC->objtypeh->getHandlerFor(Obj::HERO, h->type->heroClass->getIndex())->getTemplates().front();
h->appearance = VLC->objtypeh->getHandlerFor(Obj::HERO, h->getHeroClassID().getNum())->getTemplates().front();
h->setOwner(player);
h->setMovementPoints(h->movementPointsLimit(true));

View File

@ -292,7 +292,7 @@ TeleporterTilesVector CPathfinderHelper::getTeleportExits(const PathNodeInfo & s
{
auto * town = dynamic_cast<const CGTownInstance *>(source.nodeObject);
assert(town);
if (town && town->getFaction() == FactionID::INFERNO)
if (town && town->getFactionID() == FactionID::INFERNO)
{
/// TODO: Find way to reuse CPlayerSpecificInfoCallback::getTownsInfo
/// This may be handy if we allow to use teleportation to friendly towns

View File

@ -173,10 +173,10 @@ bool Rewardable::Limiter::heroAllowed(const CGHeroInstance * hero) const
if(!players.empty() && !vstd::contains(players, hero->getOwner()))
return false;
if(!heroes.empty() && !vstd::contains(heroes, hero->type->getId()))
if(!heroes.empty() && !vstd::contains(heroes, hero->getHeroTypeID()))
return false;
if(!heroClasses.empty() && !vstd::contains(heroClasses, hero->type->heroClass->getId()))
if(!heroClasses.empty() && !vstd::contains(heroClasses, hero->getHeroClassID()))
return false;

View File

@ -733,7 +733,7 @@ CGCreature * ObjectManager::chooseGuard(si32 strength, bool zoneGuard)
continue;
if(!cre->getAIValue()) //bug #2681
continue;
if(!vstd::contains(zone.getMonsterTypes(), cre->getFaction()))
if(!vstd::contains(zone.getMonsterTypes(), cre->getFactionID()))
continue;
if((static_cast<si32>(cre->getAIValue() * (cre->ammMin + cre->ammMax) / 2) < strength) && (strength < static_cast<si32>(cre->getAIValue()) * 100)) //at least one full monster. size between average size of given stack and 100
{

View File

@ -90,7 +90,7 @@ void TownPlacer::placeTowns(ObjectManager & manager)
totalTowns++;
//register MAIN town of zone only
map.registerZone(town->getFaction());
map.registerZone(town->getFactionID());
if(player.isValidPlayer()) //configure info for owning player
{
@ -213,7 +213,7 @@ void TownPlacer::addNewTowns(int count, bool hasFort, const PlayerColor & player
{
//FIXME: discovered bug with small zones - getPos is close to map boarder and we have outOfMap exception
//register MAIN town of zone
map.registerZone(town->getFaction());
map.registerZone(town->getFactionID());
//first town in zone goes in the middle
placeMainTown(manager, *town);
}

View File

@ -51,7 +51,7 @@ void TreasurePlacer::process()
// Add all native creatures
for(auto const & cre : VLC->creh->objects)
{
if(!cre->special && cre->getFaction() == zone.getTownType())
if(!cre->special && cre->getFactionID() == zone.getTownType())
{
creatures.push_back(cre.get());
}
@ -192,7 +192,7 @@ void TreasurePlacer::addPrisons()
{
// Hero can be used again
auto* hero = dynamic_cast<CGHeroInstance*>(obj);
prisonHeroPlacer->restoreDrawnHero(hero->getHeroType());
prisonHeroPlacer->restoreDrawnHero(hero->getHeroTypeID());
};
oi.setTemplates(Obj::PRISON, 0, zone.getTerrainType());
@ -236,9 +236,9 @@ void TreasurePlacer::addDwellings()
continue;
const auto * cre = creatures.front();
if(cre->getFaction() == zone.getTownType())
if(cre->getFactionID() == zone.getTownType())
{
auto nativeZonesCount = static_cast<float>(map.getZoneCount(cre->getFaction()));
auto nativeZonesCount = static_cast<float>(map.getZoneCount(cre->getFactionID()));
ObjectInfo oi(dwellingType, secondaryID);
setBasicProperties(oi, CompoundMapObjectID(dwellingType, secondaryID));
@ -375,7 +375,7 @@ void TreasurePlacer::addPandoraBoxesWithCreatures()
return obj;
};
oi.setTemplates(Obj::PANDORAS_BOX, 0, zone.getTerrainType());
oi.value = static_cast<ui32>(creature->getAIValue() * creaturesAmount * (1 + static_cast<float>(map.getZoneCount(creature->getFaction())) / map.getTotalZoneCount()));
oi.value = static_cast<ui32>(creature->getAIValue() * creaturesAmount * (1 + static_cast<float>(map.getZoneCount(creature->getFactionID())) / map.getTotalZoneCount()));
oi.probability = 3;
if(!oi.templates.empty())
addObjectToRandomPool(oi);
@ -555,7 +555,7 @@ void TreasurePlacer::addSeerHuts()
oi.destroyObject = destroyObject;
oi.probability = 3;
oi.setTemplates(Obj::SEER_HUT, randomAppearance, zone.getTerrainType());
oi.value = static_cast<ui32>(((2 * (creature->getAIValue()) * creaturesAmount * (1 + static_cast<float>(map.getZoneCount(creature->getFaction())) / map.getTotalZoneCount())) - 4000) / 3);
oi.value = static_cast<ui32>(((2 * (creature->getAIValue()) * creaturesAmount * (1 + static_cast<float>(map.getZoneCount(creature->getFactionID())) / map.getTotalZoneCount())) - 4000) / 3);
if (oi.value > zone.getMaxTreasureValue())
{
continue;

View File

@ -26,7 +26,7 @@ void CSerializer::addStdVecItems(CGameState *gs, LibClasses *lib)
registerVectoredType<CGObjectInstance, ObjectInstanceID>(&gs->map->objects,
[](const CGObjectInstance &obj){ return obj.id; });
registerVectoredType<CGHeroInstance, HeroTypeID>(&gs->map->allHeroes,
[](const CGHeroInstance &h){ return h.type->getId(); });
[](const CGHeroInstance &h){ return h.getHeroType()->getId(); });
registerVectoredType<CArtifactInstance, ArtifactInstanceID>(&gs->map->artInstances,
[](const CArtifactInstance &artInst){ return artInst.getId(); });
registerVectoredType<CQuest, si32>(&gs->map->quests,

View File

@ -63,6 +63,7 @@ enum class ESerializationVersion : int32_t
REGION_LABEL, // 864 - labels for campaign regions
SPELL_RESEARCH, // 865 - spell research
LOCAL_PLAYER_STATE_DATA, // 866 - player state contains arbitrary client-side data
REMOVE_TOWN_PTR, // 867 - removed pointer to CTown from CGTownInstance
CURRENT = LOCAL_PLAYER_STATE_DATA
CURRENT = REMOVE_TOWN_PTR
};

View File

@ -88,7 +88,7 @@ void Moat::convertBonus(const Mechanics * m, std::vector<Bonus> & converted) con
if(m->battle()->battleGetDefendedTown() && m->battle()->battleGetFortifications().hasMoat)
{
nb.sid = BonusSourceID(m->battle()->battleGetDefendedTown()->town->buildings.at(BuildingID::CITADEL)->getUniqueTypeID());
nb.sid = BonusSourceID(m->battle()->battleGetDefendedTown()->getTown()->buildings.at(BuildingID::CITADEL)->getUniqueTypeID());
nb.source = BonusSource::TOWN_STRUCTURE;
}
else

View File

@ -79,7 +79,7 @@ bool Summon::applicable(Problem & problem, const Mechanics * m) const
text.replaceNamePlural(elemental->creatureId());
if(caster->type->gender == EHeroGender::FEMALE)
if(caster->gender == EHeroGender::FEMALE)
text.replaceLocalString(EMetaText::GENERAL_TXT, 540);
else
text.replaceLocalString(EMetaText::GENERAL_TXT, 539);

View File

@ -138,25 +138,11 @@ void Initializer::initialize(CGHeroInstance * o)
o->subID = 0;
o->tempOwner = PlayerColor::NEUTRAL;
}
if(o->ID == Obj::HERO)
if(o->getHeroTypeID().hasValue())
{
for(auto const & t : VLC->heroh->objects)
{
if(t->heroClass->getId() == HeroClassID(o->subID))
{
o->type = t.get();
break;
}
}
}
if(o->type)
{
// o->type = VLC->heroh->objects.at(o->subID);
o->gender = o->type->gender;
o->randomizeArmy(o->type->heroClass->faction);
o->gender = o->getHeroType()->gender;
o->randomizeArmy(o->getFactionID());
}
}
@ -304,7 +290,7 @@ void Inspector::updateProperties(CGHeroInstance * o)
auto isPrison = o->ID == Obj::PRISON;
addProperty("Owner", o->tempOwner, new OwnerDelegate(controller, isPrison), isPrison); //field is not editable for prison
addProperty<int>("Experience", o->exp, false);
addProperty("Hero class", o->type ? o->type->heroClass->getNameTranslated() : "", true);
addProperty("Hero class", o->getHeroClassID().hasValue() ? o->getHeroClass()->getNameTranslated() : "", true);
{ //Gender
auto * delegate = new InspectorDelegate;
@ -319,20 +305,20 @@ void Inspector::updateProperties(CGHeroInstance * o)
addProperty("Skills", PropertyEditorPlaceholder(), delegate, false);
addProperty("Spells", PropertyEditorPlaceholder(), new HeroSpellDelegate(*o), false);
if(o->type || o->ID == Obj::PRISON)
if(o->getHeroTypeID().hasValue() || o->ID == Obj::PRISON)
{ //Hero type
auto * delegate = new InspectorDelegate;
for(int i = 0; i < VLC->heroh->objects.size(); ++i)
for(const auto & heroPtr : VLC->heroh->objects)
{
if(controller.map()->allowedHeroes.count(HeroTypeID(i)) != 0)
if(controller.map()->allowedHeroes.count(heroPtr->getId()) != 0)
{
if(o->ID == Obj::PRISON || (o->type && VLC->heroh->objects[i]->heroClass->getIndex() == o->type->heroClass->getIndex()))
if(o->ID == Obj::PRISON || heroPtr->heroClass->getIndex() == o->getHeroClassID())
{
delegate->options.push_back({QObject::tr(VLC->heroh->objects[i]->getNameTranslated().c_str()), QVariant::fromValue(VLC->heroh->objects[i]->getId().getNum())});
delegate->options.push_back({QObject::tr(heroPtr->getNameTranslated().c_str()), QVariant::fromValue(heroPtr->getIndex())});
}
}
}
addProperty("Hero type", o->type ? o->type->getNameTranslated() : "", delegate, false);
addProperty("Hero type", o->getHeroTypeID().hasValue() ? o->getHeroType()->getNameTranslated() : "", delegate, false);
}
}
@ -706,13 +692,10 @@ void Inspector::setProperty(CGHeroInstance * o, const QString & key, const QVari
for(auto const & t : VLC->heroh->objects)
{
if(t->getId() == value.toInt())
{
o->subID = value.toInt();
o->type = t.get();
}
}
o->gender = o->type->gender;
o->randomizeArmy(o->type->heroClass->faction);
o->gender = o->getHeroType()->gender;
o->randomizeArmy(o->getHeroType()->heroClass->faction);
updateProperties(); //updating other properties after change
}
}

View File

@ -331,7 +331,7 @@ void TownBuildingsDelegate::setEditorData(QWidget *editor, const QModelIndex &in
{
if(auto * ed = qobject_cast<TownBuildingsWidget *>(editor))
{
auto * ctown = town.town;
auto * ctown = town.getTown();
if(!ctown)
ctown = VLC->townh->randomTown;
if(!ctown)

View File

@ -100,7 +100,7 @@ void TownEventDialog::initResources()
void TownEventDialog::initBuildings()
{
auto * ctown = town.town;
auto * ctown = town.getTown();
if (!ctown)
ctown = VLC->townh->randomTown;
if (!ctown)
@ -156,7 +156,7 @@ QStandardItem * TownEventDialog::addBuilding(const CTown& ctown, BuildingID buil
void TownEventDialog::initCreatures()
{
auto creatures = params.value("creatures").toList();
auto * ctown = town.town;
auto * ctown = town.getTown();
if (!ctown)
ui->creaturesTable->setRowCount(GameConstants::CREATURES_PER_TOWN);
else

View File

@ -138,7 +138,7 @@ void MapController::repairMap(CMap * map) const
// FIXME: How about custom scenarios where defeated hero cannot be hired again?
map->allowedHeroes.insert(nih->getHeroType());
map->allowedHeroes.insert(nih->getHeroTypeID());
auto const & type = VLC->heroh->objects[nih->subID];
assert(type->heroClass);
@ -154,10 +154,6 @@ void MapController::repairMap(CMap * map) const
nih->subTypeName = "prison";
nih->subID = 0;
}
if(obj->ID != Obj::RANDOM_HERO)
nih->type = type.get();
if(nih->ID == Obj::HERO) //not prison
nih->appearance = VLC->objtypeh->getHandlerFor(Obj::HERO, type->heroClass->getIndex())->getTemplates().front();
//fix spellbook

View File

@ -77,12 +77,10 @@ PlayerParams::PlayerParams(MapController & ctrl, int playerId, QWidget *parent)
{
if(auto town = dynamic_cast<CGTownInstance*>(controller.map()->objects[i].get()))
{
auto * ctown = town->town;
auto * ctown = town->getTown();
if(!ctown)
{
ctown = VLC->townh->randomTown;
town->town = ctown;
}
if(ctown && town->getOwner().getNum() == playerColor)
{
if(playerInfo.hasMainTown && playerInfo.posOfMainTown == town->pos)

View File

@ -122,13 +122,13 @@ std::set<Validator::Issue> Validator::validate(const CMap * map)
++amountOfHeroes[ins->getOwner()];
}
if(ins->type)
if(ins->getHeroTypeID().hasValue())
{
if(map->allowedHeroes.count(ins->getHeroType()) == 0)
issues.insert({ tr("Hero %1 is prohibited by map settings").arg(ins->type->getNameTranslated().c_str()), false });
if(map->allowedHeroes.count(ins->getHeroTypeID()) == 0)
issues.insert({ tr("Hero %1 is prohibited by map settings").arg(ins->getHeroType()->getNameTranslated().c_str()), false });
if(!allHeroesOnMap.insert(ins->type).second)
issues.insert({ tr("Hero %1 has duplicate on map").arg(ins->type->getNameTranslated().c_str()), false });
if(!allHeroesOnMap.insert(ins->getHeroType()).second)
issues.insert({ tr("Hero %1 has duplicate on map").arg(ins->getHeroType()->getNameTranslated().c_str()), false });
}
else if(ins->ID != Obj::RANDOM_HERO)
issues.insert({ tr("Hero %1 has an empty type and must be removed").arg(ins->instanceName.c_str()), true });

View File

@ -46,7 +46,7 @@ const std::vector<CreatureProxy::CustomRegType> CreatureProxy::REGISTER_CUSTOM =
{"getLevel", LuaMethodWrapper<Creature, decltype(&Creature::getLevel), &Creature::getLevel>::invoke, false},
{"getGrowth", LuaMethodWrapper<Creature, decltype(&Creature::getGrowth), &Creature::getGrowth>::invoke, false},
{"getHorde", LuaMethodWrapper<Creature, decltype(&Creature::getHorde), &Creature::getHorde>::invoke, false},
{"getFaction", LuaMethodWrapper<Creature, decltype(&Creature::getFaction), &Creature::getFaction>::invoke, false},
{"getFactionID", LuaMethodWrapper<Creature, decltype(&Creature::getFactionID), &Creature::getFactionID>::invoke, false},
{"getBaseAttack", LuaMethodWrapper<Creature, decltype(&Creature::getBaseAttack), &Creature::getBaseAttack>::invoke, false},
{"getBaseDefense", LuaMethodWrapper<Creature, decltype(&Creature::getBaseDefense), &Creature::getBaseDefense>::invoke, false},

View File

@ -162,7 +162,7 @@ void CGameHandler::levelUpHero(const CGHeroInstance * hero)
hlu.player = hero->tempOwner;
hlu.heroId = hero->id;
hlu.primskill = primarySkill;
hlu.skills = hero->getLevelUpProposedSecondarySkills(heroPool->getHeroSkillsRandomGenerator(hero->getHeroType()));
hlu.skills = hero->getLevelUpProposedSecondarySkills(heroPool->getHeroSkillsRandomGenerator(hero->getHeroTypeID()));
if (hlu.skills.size() == 0)
{
@ -553,7 +553,7 @@ void CGameHandler::init(StartInfo *si, Load::ProgressAccumulator & progressTrack
for (auto & elem : gs->map->allHeroes)
{
if(elem)
heroPool->getHeroSkillsRandomGenerator(elem->getHeroType()); // init RMG seed
heroPool->getHeroSkillsRandomGenerator(elem->getHeroTypeID()); // init RMG seed
}
reinitScripting();
@ -569,12 +569,12 @@ void CGameHandler::setPortalDwelling(const CGTownInstance * town, bool forced=fa
return;
}
if (forced || town->creatures.at(town->town->creatures.size()).second.empty())//we need to change creature
if (forced || town->creatures.at(town->getTown()->creatures.size()).second.empty())//we need to change creature
{
SetAvailableCreatures ssi;
ssi.tid = town->id;
ssi.creatures = town->creatures;
ssi.creatures[town->town->creatures.size()].second.clear();//remove old one
ssi.creatures[town->getTown()->creatures.size()].second.clear();//remove old one
std::set<CreatureID> availableCreatures;
for (const auto & dwelling : p->getOwnedObjects())
@ -590,13 +590,13 @@ void CGameHandler::setPortalDwelling(const CGTownInstance * town, bool forced=fa
if (clear)
{
ssi.creatures[town->town->creatures.size()].first = std::max(1, (creatureId.toEntity(VLC)->getGrowth())/2);
ssi.creatures[town->getTown()->creatures.size()].first = std::max(1, (creatureId.toEntity(VLC)->getGrowth())/2);
}
else
{
ssi.creatures[town->town->creatures.size()].first = creatureId.toEntity(VLC)->getGrowth();
ssi.creatures[town->getTown()->creatures.size()].first = creatureId.toEntity(VLC)->getGrowth();
}
ssi.creatures[town->town->creatures.size()].second.push_back(creatureId);
ssi.creatures[town->getTown()->creatures.size()].second.push_back(creatureId);
sendAndApply(ssi);
}
}
@ -657,7 +657,7 @@ void CGameHandler::onNewTurn()
PlayerColor player = t->tempOwner;
if(t->hasBuilt(BuildingID::GRAIL)
&& t->town->buildings.at(BuildingID::GRAIL)->height == CBuilding::HEIGHT_SKYSHIP)
&& t->getTown()->buildings.at(BuildingID::GRAIL)->height == CBuilding::HEIGHT_SKYSHIP)
{
// Skyship, probably easier to handle same as Veil of darkness
// do it every new day before veils
@ -1048,7 +1048,7 @@ bool CGameHandler::teleportHero(ObjectInstanceID hid, ObjectInstanceID dstid, ui
if (((h->getOwner() != t->getOwner())
&& complain("Cannot teleport hero to another player"))
|| (from->town->faction->getId() != t->town->faction->getId()
|| (from->getFactionID() != t->getFactionID()
&& complain("Source town and destination town should belong to the same faction"))
|| ((!from || !from->hasBuilt(BuildingSubID::CASTLE_GATE))
@ -1212,7 +1212,7 @@ void CGameHandler::visitCastleObjects(const CGTownInstance * t, std::vector<cons
for (auto & building : t->rewardableBuildings)
{
if (!t->town->buildings.at(building.first)->manualHeroVisit && t->hasBuilt(building.first))
if (!t->getTown()->buildings.at(building.first)->manualHeroVisit && t->hasBuilt(building.first))
buildingsToVisit.push_back(building.first);
}
@ -2036,12 +2036,12 @@ bool CGameHandler::buildStructure(ObjectInstanceID tid, BuildingID requestedID,
const CGTownInstance * t = getTown(tid);
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->getNameTranslated() % requestedID);
if(!t->getTown()->buildings.count(requestedID))
COMPLAIN_RETF("Town of faction %s does not have info about building ID=%s!", t->getFaction()->getNameTranslated() % requestedID);
if(t->hasBuilt(requestedID))
COMPLAIN_RETF("Building %s is already built in %s", t->town->buildings.at(requestedID)->getNameTranslated() % t->getNameTranslated());
COMPLAIN_RETF("Building %s is already built in %s", t->getTown()->buildings.at(requestedID)->getNameTranslated() % t->getNameTranslated());
const CBuilding * requestedBuilding = t->town->buildings.at(requestedID);
const CBuilding * requestedBuilding = t->getTown()->buildings.at(requestedID);
//Vector with future list of built building and buildings in auto-mode that are not yet built.
std::vector<const CBuilding*> remainingAutoBuildings;
@ -2081,7 +2081,7 @@ bool CGameHandler::buildStructure(ObjectInstanceID tid, BuildingID requestedID,
int level = BuildingID::getLevelFromDwelling(buildingID);
int upgradeNumber = BuildingID::getUpgradedFromDwelling(buildingID);
if(upgradeNumber >= t->town->creatures.at(level).size())
if(upgradeNumber >= t->getTown()->creatures.at(level).size())
{
complain(boost::str(boost::format("Error encountered when building dwelling (bid=%s):"
"no creature found (upgrade number %d, level %d!")
@ -2089,7 +2089,7 @@ bool CGameHandler::buildStructure(ObjectInstanceID tid, BuildingID requestedID,
return;
}
const CCreature * crea = t->town->creatures.at(level).at(upgradeNumber).toCreature();
const CCreature * crea = t->getTown()->creatures.at(level).at(upgradeNumber).toCreature();
SetAvailableCreatures ssi;
ssi.tid = t->id;
@ -2099,7 +2099,7 @@ bool CGameHandler::buildStructure(ObjectInstanceID tid, BuildingID requestedID,
ssi.creatures[level].second.push_back(crea->getId());
sendAndApply(ssi);
}
if(t->town->buildings.at(buildingID)->subId == BuildingSubID::PORTAL_OF_SUMMONING)
if(t->getTown()->buildings.at(buildingID)->subId == BuildingSubID::PORTAL_OF_SUMMONING)
{
setPortalDwelling(t);
}
@ -2110,9 +2110,9 @@ bool CGameHandler::buildStructure(ObjectInstanceID tid, BuildingID requestedID,
{
auto isMageGuild = (buildingID <= BuildingID::MAGES_GUILD_5 && buildingID >= BuildingID::MAGES_GUILD_1);
auto isLibrary = isMageGuild ? false
: t->town->buildings.at(buildingID)->subId == BuildingSubID::EBuildingSubID::LIBRARY;
: t->getTown()->buildings.at(buildingID)->subId == BuildingSubID::EBuildingSubID::LIBRARY;
if(isMageGuild || isLibrary || (t->getFaction() == ETownType::CONFLUX && buildingID == BuildingID::GRAIL))
if(isMageGuild || isLibrary || (t->getFactionID() == ETownType::CONFLUX && buildingID == BuildingID::GRAIL))
{
if(t->visitingHero)
giveSpells(t,t->visitingHero);
@ -2128,7 +2128,7 @@ bool CGameHandler::buildStructure(ObjectInstanceID tid, BuildingID requestedID,
};
//Init the vectors
for(auto & build : t->town->buildings)
for(auto & build : t->getTown()->buildings)
{
if(t->hasBuilt(build.first))
{
@ -2212,7 +2212,7 @@ bool CGameHandler::visitTownBuilding(ObjectInstanceID tid, BuildingID bid)
if(!t->hasBuilt(bid))
return false;
auto subID = t->town->buildings.at(bid)->subId;
auto subID = t->getTown()->buildings.at(bid)->subId;
if(subID == BuildingSubID::EBuildingSubID::BANK)
{
@ -2224,7 +2224,7 @@ bool CGameHandler::visitTownBuilding(ObjectInstanceID tid, BuildingID bid)
return true;
}
if (t->rewardableBuildings.count(bid) && t->visitingHero && t->town->buildings.at(bid)->manualHeroVisit)
if (t->rewardableBuildings.count(bid) && t->visitingHero && t->getTown()->buildings.at(bid)->manualHeroVisit)
{
std::vector<BuildingID> buildingsToVisit;
std::vector<const CGHeroInstance*> visitors;

View File

@ -47,8 +47,8 @@ TavernHeroSlot HeroPoolProcessor::selectSlotForRole(const PlayerColor & player,
// try to find "better" slot to overwrite
// we want to avoid overwriting retreated heroes when tavern still has slot with random hero
// as well as avoid overwriting surrendered heroes if we can overwrite retreated hero
auto roleLeft = heroesPool->getSlotRole(heroes[0]->getHeroType());
auto roleRight = heroesPool->getSlotRole(heroes[1]->getHeroType());
auto roleLeft = heroesPool->getSlotRole(heroes[0]->getHeroTypeID());
auto roleRight = heroesPool->getSlotRole(heroes[1]->getHeroTypeID());
if (roleLeft > roleRight)
return TavernHeroSlot::RANDOM;
@ -70,7 +70,7 @@ void HeroPoolProcessor::onHeroSurrendered(const PlayerColor & color, const CGHer
sah.slotID = selectSlotForRole(color, sah.roleID);
sah.player = color;
sah.hid = hero->getHeroType();
sah.hid = hero->getHeroTypeID();
sah.replenishPoints = false;
gameHandler->sendAndApply(sah);
}
@ -82,9 +82,9 @@ void HeroPoolProcessor::onHeroEscaped(const PlayerColor & color, const CGHeroIns
sah.slotID = selectSlotForRole(color, sah.roleID);
sah.player = color;
sah.hid = hero->getHeroType();
sah.hid = hero->getHeroTypeID();
sah.army.clearSlots();
sah.army.setCreature(SlotID(0), hero->type->initialArmy.at(0).creature, 1);
sah.army.setCreature(SlotID(0), hero->getHeroType()->initialArmy.at(0).creature, 1);
sah.replenishPoints = false;
gameHandler->sendAndApply(sah);
@ -112,7 +112,7 @@ void HeroPoolProcessor::selectNewHeroForSlot(const PlayerColor & color, TavernHe
if (newHero)
{
sah.hid = newHero->getHeroType();
sah.hid = newHero->getHeroTypeID();
if (giveArmy)
{
@ -123,7 +123,7 @@ void HeroPoolProcessor::selectNewHeroForSlot(const PlayerColor & color, TavernHe
{
sah.roleID = TavernSlotRole::SINGLE_UNIT;
sah.army.clearSlots();
sah.army.setCreature(SlotID(0), newHero->type->initialArmy[0].creature, 1);
sah.army.setCreature(SlotID(0), newHero->getHeroType()->initialArmy[0].creature, 1);
}
}
else
@ -208,7 +208,7 @@ bool HeroPoolProcessor::hireHero(const ObjectInstanceID & objectID, const HeroTy
for(const auto & hero : recruitableHeroes)
{
if(hero->getHeroType() == heroToRecruit)
if(hero->getHeroTypeID() == heroToRecruit)
recruitedHero = hero;
}
@ -221,7 +221,7 @@ bool HeroPoolProcessor::hireHero(const ObjectInstanceID & objectID, const HeroTy
HeroRecruited hr;
hr.tid = mapObject->id;
hr.hid = recruitedHero->getHeroType();
hr.hid = recruitedHero->getHeroTypeID();
hr.player = player;
hr.tile = recruitedHero->convertFromVisitablePos(targetPos );
if(gameHandler->getTile(targetPos)->isWater() && !recruitedHero->boat)
@ -258,14 +258,14 @@ std::vector<const CHeroClass *> HeroPoolProcessor::findAvailableClassesFor(const
for(const auto & elem : heroesPool->unusedHeroesFromPool())
{
if (vstd::contains(result, elem.second->type->heroClass))
if (vstd::contains(result, elem.second->getHeroClass()))
continue;
bool heroAvailable = heroesPool->isHeroAvailableFor(elem.first, player);
bool heroClassBanned = elem.second->type->heroClass->tavernProbability(factionID) == 0;
bool heroClassBanned = elem.second->getHeroClass()->tavernProbability(factionID) == 0;
if(heroAvailable && !heroClassBanned)
result.push_back(elem.second->type->heroClass);
result.push_back(elem.second->getHeroClass());
}
return result;
@ -282,7 +282,7 @@ std::vector<CGHeroInstance *> HeroPoolProcessor::findAvailableHeroesFor(const Pl
assert(!vstd::contains(result, elem.second));
bool heroAvailable = heroesPool->isHeroAvailableFor(elem.first, player);
bool heroClassMatches = elem.second->type->heroClass == heroClass;
bool heroClassMatches = elem.second->getHeroClass() == heroClass;
if(heroAvailable && heroClassMatches)
result.push_back(elem.second);
@ -318,7 +318,7 @@ const CHeroClass * HeroPoolProcessor::pickClassFor(bool isNative, const PlayerCo
continue;
bool hasSameClass = vstd::contains_if(currentTavern, [&](const CGHeroInstance * hero){
return hero->type->heroClass == heroClass;
return hero->getHeroClass() == heroClass;
});
if (hasSameClass)

View File

@ -95,10 +95,10 @@ void NewTurnProcessor::handleTownEvents(const CGTownInstance * town)
// 1. Building exists in town (don't attempt to build Lvl 5 guild in Fortress
// 2. Building was not built yet
// othervice, silently ignore / skip it
if (town->town->buildings.count(i) && !town->hasBuilt(i))
if (town->getTown()->buildings.count(i) && !town->hasBuilt(i))
{
gameHandler->buildStructure(town->id, i, true);
iw.components.emplace_back(ComponentType::BUILDING, BuildingTypeUniqueID(town->getFaction(), i));
iw.components.emplace_back(ComponentType::BUILDING, BuildingTypeUniqueID(town->getFactionID(), i));
}
}
@ -246,7 +246,7 @@ SetAvailableCreatures NewTurnProcessor::generateTownGrowth(const CGTownInstance
sac.tid = t->id;
sac.creatures = t->creatures;
for (int k=0; k < t->town->creatures.size(); k++)
for (int k=0; k < t->getTown()->creatures.size(); k++)
{
if (t->creatures.at(k).second.empty())
continue;
@ -345,7 +345,7 @@ void NewTurnProcessor::updateNeutralTownGarrison(const CGTownInstance * t, int c
{
const auto * creature = slot.second->type;
if (creature->getFaction() != t->getFaction())
if (creature->getFactionID() != t->getFactionID())
continue;
if (creature->getLevel() != tierToGrow)
@ -518,7 +518,7 @@ std::tuple<EWeekType, CreatureID> NewTurnProcessor::pickWeekType(bool newMonth)
{
newMonster.second = VLC->creh->pickRandomMonster(gameHandler->getRandomGenerator());
} while (VLC->creh->objects[newMonster.second] &&
(*VLC->townh)[VLC->creatures()->getById(newMonster.second)->getFaction()]->town == nullptr); // find first non neutral creature
(*VLC->townh)[VLC->creatures()->getById(newMonster.second)->getFactionID()]->town == nullptr); // find first non neutral creature
return { EWeekType::BONUS_GROWTH, newMonster.second};
}

View File

@ -370,7 +370,7 @@ void PlayerMessageProcessor::cheatBuildTown(PlayerColor player, const CGTownInst
if (!town)
return;
for (auto & build : town->town->buildings)
for (auto & build : town->getTown()->buildings)
{
if (!town->hasBuilt(build.first)
&& !build.second->getNameTranslated().empty()

View File

@ -100,7 +100,7 @@ TEST_F(CCreatureTest, DISABLED_JsonUpdate)
EXPECT_EQ(subject->getFightValue(), 2420);
EXPECT_EQ(subject->getLevel(), 6);
EXPECT_EQ(subject->getFaction().getNum(), 55);
EXPECT_EQ(subject->getFactionID().getNum(), 55);
EXPECT_TRUE(subject->isDoubleWide());
}

View File

@ -44,7 +44,7 @@ public:
MOCK_CONST_METHOD0(getLevel, int32_t());
MOCK_CONST_METHOD0(getGrowth, int32_t());
MOCK_CONST_METHOD0(getHorde, int32_t());
MOCK_CONST_METHOD0(getFaction, FactionID());
MOCK_CONST_METHOD0(getFactionID, FactionID());
MOCK_CONST_METHOD0(getBaseAttack, int32_t());
MOCK_CONST_METHOD0(getBaseDefense, int32_t());

View File

@ -82,7 +82,7 @@ public:
MOCK_CONST_METHOD1(willMove, bool(int));
MOCK_CONST_METHOD1(waited, bool(int));
MOCK_CONST_METHOD0(getFaction, FactionID());
MOCK_CONST_METHOD0(getFactionID, FactionID());
MOCK_CONST_METHOD1(battleQueuePhase, battle::BattlePhases::Type(int));