mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-22 22:13:35 +02:00
Reduce usage of pointers to VLC entities
Final goal (of multiple PR's) is to remove all remaining pointers from serializeable game state, and replace them with either identifiers or with shared/unique pointers. CGTownInstance::town and CGHeroInstance::type members have been removed. Now this data is computed dynamically using subID member. VLC entity of a town can now be accessed via following methods: - getFactionID() returns ID of a faction - getFaction() returns pointer to a faction - getTown() returns pointer to a town VLC entity of a hero can now be accessed via following methods: - getHeroTypeID() returns ID of a hero - getHeroClassID() returns ID of a hero class - getHeroType() returns pointer to a hero - getHeroClass() returns pointer to a hero class
This commit is contained in:
parent
81f0222c68
commit
3dd4fa2528
@ -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;
|
||||
}
|
||||
|
@ -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());
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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));
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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)));
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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));
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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());
|
||||
}
|
||||
|
@ -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!");
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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++)
|
||||
|
@ -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));
|
||||
|
@ -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]);
|
||||
|
@ -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), []()
|
||||
{
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
@ -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
|
||||
|
@ -117,7 +117,7 @@ int32_t CCreature::getHorde() const
|
||||
return hordeGrowth;
|
||||
}
|
||||
|
||||
FactionID CCreature::getFaction() const
|
||||
FactionID CCreature::getFactionID() const
|
||||
{
|
||||
return FactionID(faction);
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -92,7 +92,7 @@ FactionID CFaction::getId() const
|
||||
return FactionID(index);
|
||||
}
|
||||
|
||||
FactionID CFaction::getFaction() const
|
||||
FactionID CFaction::getFactionID() const
|
||||
{
|
||||
return FactionID(index);
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
{
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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))
|
||||
|
@ -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;
|
||||
|
@ -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())
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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());
|
||||
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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));
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
||||
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
};
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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 });
|
||||
|
@ -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},
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -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};
|
||||
}
|
||||
|
@ -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()
|
||||
|
@ -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());
|
||||
}
|
||||
|
||||
|
@ -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());
|
||||
|
@ -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));
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user