1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-11-06 09:09:40 +02:00

Reduce usage of implicit conversions to int

This commit is contained in:
Ivan Savenko
2025-04-19 16:12:07 +03:00
parent 4d57a8ed36
commit 829739da24
64 changed files with 220 additions and 200 deletions

View File

@@ -325,7 +325,7 @@ void AIGateway::heroExchangeStarted(ObjectInstanceID hero1, ObjectInstanceID her
void AIGateway::heroPrimarySkillChanged(const CGHeroInstance * hero, PrimarySkill which, si64 val)
{
LOG_TRACE_PARAMS(logAi, "which '%i', val '%i'", static_cast<int>(which) % val);
LOG_TRACE_PARAMS(logAi, "which '%i', val '%i'", which.getNum() % val);
NET_EVENT_HANDLER;
}
@@ -1542,7 +1542,7 @@ void AIGateway::tryRealize(Goals::Trade & g) //trade
int toGive;
int toGet;
m->getOffer(res, g.resID, toGive, toGet, EMarketMode::RESOURCE_RESOURCE);
m->getOffer(res.getNum(), g.resID, toGive, toGet, EMarketMode::RESOURCE_RESOURCE);
toGive = static_cast<int>(toGive * (it->resVal / toGive)); //round down
//TODO trade only as much as needed
if (toGive) //don't try to sell 0 resources

View File

@@ -351,7 +351,7 @@ void BuildAnalyzer::updateDailyIncome()
}
}
bool BuildAnalyzer::hasAnyBuilding(int32_t alignment, BuildingID bid) const
bool BuildAnalyzer::hasAnyBuilding(FactionID alignment, BuildingID bid) const
{
for(auto tdi : developmentInfos)
{

View File

@@ -97,7 +97,7 @@ public:
TResources getDailyIncome() const { return dailyIncome; }
float getGoldPressure() const { return goldPressure; }
bool isGoldPressureHigh() const;
bool hasAnyBuilding(int32_t alignment, BuildingID bid) const;
bool hasAnyBuilding(FactionID alignment, BuildingID bid) const;
private:
BuildingInfo getBuildingOrPrerequisite(

View File

@@ -642,7 +642,7 @@ bool Nullkiller::handleTrading()
{
bool haveTraded = false;
bool shouldTryToTrade = true;
int marketId = -1;
ObjectInstanceID marketId;
for (auto town : cb->getTownsInfo())
{
if (town->hasBuiltSomeTradeBuilding())
@@ -650,9 +650,9 @@ bool Nullkiller::handleTrading()
marketId = town->id;
}
}
if (marketId == -1)
if (!marketId.hasValue())
return false;
if (const CGObjectInstance* obj = cb->getObj(ObjectInstanceID(marketId), false))
if (const CGObjectInstance* obj = cb->getObj(marketId, false))
{
if (const auto* m = dynamic_cast<const IMarket*>(obj))
{

View File

@@ -380,7 +380,7 @@ float RewardEvaluator::getEnemyHeroStrategicalValue(const CGHeroInstance * enemy
return std::min(1.5f, objectValue * 0.9f + (1.5f - (1.5f / (1 + enemy->level))));
}
float RewardEvaluator::getResourceRequirementStrength(int resType) const
float RewardEvaluator::getResourceRequirementStrength(GameResID resType) const
{
TResources requiredResources = ai->buildAnalyzer->getResourcesRequiredNow();
TResources dailyIncome = ai->buildAnalyzer->getDailyIncome();
@@ -396,7 +396,7 @@ float RewardEvaluator::getResourceRequirementStrength(int resType) const
return std::min(ratio, 1.0f);
}
float RewardEvaluator::getTotalResourceRequirementStrength(int resType) const
float RewardEvaluator::getTotalResourceRequirementStrength(GameResID resType) const
{
TResources requiredResources = ai->buildAnalyzer->getTotalResourcesRequired();
TResources dailyIncome = ai->buildAnalyzer->getDailyIncome();
@@ -987,12 +987,12 @@ public:
float totalPower = 0;
// Map to store the aggregated power of creatures by CreatureID
std::map<int, float> totalPowerByCreatureID;
std::map<CreatureID, float> totalPowerByCreatureID;
// Calculate hero power and total power by CreatureID
for (const auto & slot : hero->Slots())
{
int creatureID = slot.second->getCreatureID();
CreatureID creatureID = slot.second->getCreatureID();
float slotPower = slot.second->getPower();
// Add the power of this slot to the heroPower
@@ -1220,7 +1220,7 @@ public:
}
else if(bi.id >= BuildingID::MAGES_GUILD_1 && bi.id <= BuildingID::MAGES_GUILD_5)
{
evaluationContext.skillReward += 2 * (bi.id - BuildingID::MAGES_GUILD_1);
evaluationContext.skillReward += 2 * buildThis.town->spellsAtLevel(bi.id.getMagesGuildLevel(), false);
if (!alreadyOwn && evaluationContext.evaluator.ai->cb->canBuildStructure(buildThis.town, highestMageGuildPossible) != EBuildingState::FORBIDDEN)
{
for (auto hero : evaluationContext.evaluator.ai->cb->getHeroesInfo())

View File

@@ -38,11 +38,11 @@ public:
uint64_t getArmyGrowth(const CGObjectInstance * target, const CGHeroInstance * hero, const CCreatureSet * army) const;
int getGoldCost(const CGObjectInstance * target, const CGHeroInstance * hero, const CCreatureSet * army) const;
float getEnemyHeroStrategicalValue(const CGHeroInstance * enemy) const;
float getResourceRequirementStrength(int resType) const;
float getResourceRequirementStrength(GameResID resType) const;
float getResourceRequirementStrength(const TResources & res) const;
float getStrategicalValue(const CGObjectInstance * target, const CGHeroInstance * hero = nullptr) const;
float getConquestValue(const CGObjectInstance* target) const;
float getTotalResourceRequirementStrength(int resType) const;
float getTotalResourceRequirementStrength(GameResID resType) const;
float evaluateWitchHutSkillScore(const CGObjectInstance * hut, const CGHeroInstance * hero, HeroRole role) const;
float getSkillReward(const CGObjectInstance * target, const CGHeroInstance * hero, HeroRole role) const;
int32_t getGoldReward(const CGObjectInstance * target, const CGHeroInstance * hero) const;

View File

@@ -29,7 +29,7 @@ BuildThis::BuildThis(BuildingID Bid, const CGTownInstance * tid)
tid,
nullptr);
bid = Bid;
bid = Bid.getNum();
town = tid;
}

View File

@@ -34,7 +34,7 @@ namespace Goals
BuildThis(const BuildingInfo & buildingInfo, const TownDevelopmentInfo & townInfo) //should be private, but unit test uses it
: ElementarGoal(Goals::BUILD_STRUCTURE), buildingInfo(buildingInfo), townInfo(townInfo)
{
bid = buildingInfo.id;
bid = buildingInfo.id.getNum();
town = townInfo.town;
}
BuildThis(BuildingID Bid, const CGTownInstance * tid);

View File

@@ -94,7 +94,7 @@ namespace Goals
bool isObjectAffected(ObjectInstanceID id) const override
{
return (AbstractGoal::hero && AbstractGoal::hero->id == id)
|| AbstractGoal::objid == id
|| AbstractGoal::objid == id.getNum()
|| (AbstractGoal::town && AbstractGoal::town->id == id);
}

View File

@@ -87,7 +87,7 @@ uint64_t CompleteQuest::getHash() const
return q.getObject(cb)->subID;
}
return q.getObject(cb)->id;
return q.getObject(cb)->id.getNum();
}
std::string CompleteQuest::questToString() const
@@ -129,7 +129,7 @@ TGoalVec CompleteQuest::missionArt(const Nullkiller * ai) const
for(auto art : q.getQuest(cb)->mission.artifacts)
{
solutions.push_back(sptr(CaptureObjectsBehavior().ofType(Obj::ARTIFACT, art)));
solutions.push_back(sptr(CaptureObjectsBehavior().ofType(Obj::ARTIFACT, art.getNum())));
}
return solutions;

View File

@@ -68,7 +68,7 @@ std::vector<ObjectInstanceID> ExecuteHeroChain::getAffectedObjects() const
bool ExecuteHeroChain::isObjectAffected(ObjectInstanceID id) const
{
if(chainPath.targetHero->id == id || objid == id)
if(chainPath.targetHero->id == id || objid == id.getNum())
return true;
for(auto & node : chainPath.nodes)

View File

@@ -34,7 +34,7 @@ namespace Goals
{
tile = cluster->blocker->visitablePos();
hero = pathToCenter.targetHero;
objid = cluster->blocker->id;
objid = cluster->blocker->id.getNum();
}
bool operator==(const UnlockCluster & other) const override;

View File

@@ -180,7 +180,7 @@ std::optional<AIPathNode *> AINodeStorage::getOrCreateNode(
const EPathfindingLayer layer,
const ChainActor * actor)
{
int bucketIndex = ((uintptr_t)actor + static_cast<uint32_t>(layer)) % ai->settings->getPathfinderBucketsCount();
int bucketIndex = ((uintptr_t)actor + layer.getNum()) % ai->settings->getPathfinderBucketsCount();
int bucketOffset = bucketIndex * ai->settings->getPathfinderBucketSize();
auto chains = nodes.get(pos);

View File

@@ -286,12 +286,12 @@ public:
inline EPathAccessibility getAccessibility(const int3 & tile, EPathfindingLayer layer) const
{
return (*this->accessibility)[tile.z][tile.x][tile.y][layer];
return (*this->accessibility)[tile.z][tile.x][tile.y][layer.getNum()];
}
inline void resetTile(const int3 & tile, EPathfindingLayer layer, EPathAccessibility tileAccessibility)
{
(*this->accessibility)[tile.z][tile.x][tile.y][layer] = tileAccessibility;
(*this->accessibility)[tile.z][tile.x][tile.y][layer.getNum()] = tileAccessibility;
}
inline int getBucket(const ChainActor * actor) const

View File

@@ -75,7 +75,7 @@ int ChainActor::maxMovePoints(CGPathNode::ELayer layer)
throw std::logic_error("Asking movement points for static actor");
#endif
return hero->movementPointsLimit(layer);
return hero->movementPointsLimit(layer != EPathfindingLayer::SAIL);
}
std::string ChainActor::toString() const

View File

@@ -59,7 +59,7 @@ void GraphPaths::calculatePaths(const CGHeroInstance * targetHero, const Nullkil
graph.copyFrom(*ai->baseGraph);
graph.connectHeroes(ai);
visualKey = std::to_string(ai->playerID) + ":" + targetHero->getNameTranslated();
visualKey = std::to_string(ai->playerID.getNum()) + ":" + targetHero->getNameTranslated();
pathNodes.clear();
GraphNodeComparer cmp(pathNodes);

View File

@@ -204,7 +204,7 @@ bool isBlockedBorderGate(int3 tileToHit) //TODO: is that function needed? should
if(!object)
return false;
if(object->id != Obj::BORDER_GATE)
if(object->ID != Obj::BORDER_GATE)
return false;
auto gate = dynamic_cast<const CGKeys *>(object);

View File

@@ -36,7 +36,7 @@ TGoalVec Build::getAllPossibleSubgoals()
if(!t->hasBuilt(ai->ah->getMaxPossibleGoldBuilding(t)) && expensiveBuilding.has_value())
{
auto potentialBuilding = expensiveBuilding.value();
switch(expensiveBuilding.value().bid)
switch(expensiveBuilding.value().bid.toEnum())
{
case BuildingID::TOWN_HALL:
case BuildingID::CITY_HALL:

View File

@@ -27,14 +27,14 @@ namespace Goals
BuildThis(BuildingID Bid, const CGTownInstance * tid)
: CGoal(Goals::BUILD_STRUCTURE)
{
bid = Bid;
bid = Bid.getNum();
town = tid;
priority = 1;
}
BuildThis(BuildingID Bid)
: CGoal(Goals::BUILD_STRUCTURE)
{
bid = Bid;
bid = Bid.getNum();
priority = 1;
}
TGoalVec getAllPossibleSubgoals() override

View File

@@ -41,7 +41,7 @@ TGoalVec CollectRes::getAllPossibleSubgoals()
switch (obj->ID.num)
{
case Obj::TREASURE_CHEST:
return resID == GameResID(EGameResID::GOLD);
return resID == GameResID(EGameResID::GOLD).getNum();
break;
case Obj::RESOURCE:
return dynamic_cast<const CGResource*>(obj)->resourceID() == GameResID(resID);
@@ -62,13 +62,13 @@ TGoalVec CollectRes::getAllPossibleSubgoals()
}
break;
case Obj::MYSTICAL_GARDEN:
if ((resID != GameResID(EGameResID::GOLD)) && (resID != GameResID(EGameResID::GEMS)))
if (resID != GameResID(EGameResID::GOLD).getNum() && resID != GameResID(EGameResID::GEMS).getNum())
return false;
break;
case Obj::WATER_WHEEL:
case Obj::LEAN_TO:
case Obj::WAGON:
if (resID != GameResID(EGameResID::GOLD))
if (resID != GameResID(EGameResID::GOLD).getNum())
return false;
break;
default:
@@ -177,7 +177,7 @@ TSubgoal CollectRes::whatToDoToTrade()
continue;
int toGive = -1;
int toReceive = -1;
m->getOffer(i, resID, toGive, toReceive, EMarketMode::RESOURCE_RESOURCE);
m->getOffer(i.getNum(), resID, toGive, toReceive, EMarketMode::RESOURCE_RESOURCE);
assert(toGive > 0 && toReceive > 0);
howManyCanWeBuy += toReceive * (ai->ah->freeResources()[i] / toGive);
}

View File

@@ -146,7 +146,7 @@ TGoalVec CompleteQuest::missionArt() const
for(auto art : q.getQuest(cb)->mission.artifacts)
{
solutions.push_back(sptr(GetArtOfType(art))); //TODO: transport?
solutions.push_back(sptr(GetArtOfType(art.getNum()))); //TODO: transport?
}
return solutions;
@@ -174,7 +174,7 @@ TGoalVec CompleteQuest::missionArmy() const
for(auto creature : q.getQuest(cb)->mission.creatures)
{
solutions.push_back(sptr(GatherTroops(creature.getId(), creature.count)));
solutions.push_back(sptr(GatherTroops(creature.getId().getNum(), creature.count)));
}
return solutions;

View File

@@ -51,7 +51,7 @@ TSubgoal Win::whatToDoToAchieve()
switch(goal.condition)
{
case EventCondition::HAVE_ARTIFACT:
return sptr(GetArtOfType(goal.objectType.as<ArtifactID>()));
return sptr(GetArtOfType(goal.objectType.as<ArtifactID>().getNum()));
case EventCondition::DESTROY:
{
if(goal.objectID != ObjectInstanceID::NONE)
@@ -151,7 +151,7 @@ TSubgoal Win::whatToDoToAchieve()
//save?
return sptr(CollectRes(goal.objectType.as<GameResID>(), goal.value));
case EventCondition::HAVE_CREATURES:
return sptr(GatherTroops(goal.objectType.as<CreatureID>(), goal.value));
return sptr(GatherTroops(goal.objectType.as<CreatureID>().getNum(), goal.value));
case EventCondition::TRANSPORT:
{
//TODO. merge with bring Grail to town? So AI will first dig grail, then transport it using this goal and builds it

View File

@@ -68,7 +68,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->getHeroClassID());
return getObjectValue(obj->ID.getNum(), hero->getHeroClassID().getNum());
}
else if(obj->ID == Obj::PRISON)
{

View File

@@ -88,7 +88,7 @@ bool AINodeStorage::isBattleNode(const CGPathNode * node) const
std::optional<AIPathNode *> AINodeStorage::getOrCreateNode(const int3 & pos, const EPathfindingLayer layer, int chainNumber)
{
auto chains = nodes[layer][pos.z][pos.x][pos.y];
auto chains = nodes[layer.getNum()][pos.z][pos.x][pos.y];
for(AIPathNode & node : chains)
{
@@ -125,7 +125,7 @@ void AINodeStorage::resetTile(const int3 & coord, EPathfindingLayer layer, EPath
{
for(int i = 0; i < NUM_CHAINS; i++)
{
AIPathNode & heroNode = nodes[layer][coord.z][coord.x][coord.y][i];
AIPathNode & heroNode = nodes[layer.getNum()][coord.z][coord.x][coord.y][i];
heroNode.chainMask = 0;
heroNode.danger = 0;
@@ -326,7 +326,7 @@ bool AINodeStorage::hasBetterChain(const PathNodeInfo & source, CDestinationNode
bool AINodeStorage::isTileAccessible(const int3 & pos, const EPathfindingLayer layer) const
{
return nodes[layer][pos.z][pos.x][pos.y][0].action != EPathNodeAction::UNKNOWN;
return nodes[layer.getNum()][pos.z][pos.x][pos.y][0].action != EPathNodeAction::UNKNOWN;
}
std::vector<AIPath> AINodeStorage::getChainInfo(const int3 & pos, bool isOnLand) const

View File

@@ -364,7 +364,7 @@ void VCAI::heroExchangeStarted(ObjectInstanceID hero1, ObjectInstanceID hero2, Q
void VCAI::heroPrimarySkillChanged(const CGHeroInstance * hero, PrimarySkill which, si64 val)
{
LOG_TRACE_PARAMS(logAi, "which '%i', val '%i'", static_cast<int>(which) % val);
LOG_TRACE_PARAMS(logAi, "which '%i', val '%i'", which.getNum() % val);
NET_EVENT_HANDLER;
}
@@ -2156,7 +2156,7 @@ void VCAI::tryRealize(Goals::Trade & g) //trade
int toGive;
int toGet;
m->getOffer(res, g.resID, toGive, toGet, EMarketMode::RESOURCE_RESOURCE);
m->getOffer(res.getNum(), g.resID, toGive, toGet, EMarketMode::RESOURCE_RESOURCE);
toGive = static_cast<int>(toGive * (it->resVal / toGive)); //round down
//TODO trade only as much as needed
if (toGive) //don't try to sell 0 resources

View File

@@ -1072,7 +1072,7 @@ void ApplyClientNetPackVisitor::visitNewObject(NewObject & pack)
void ApplyClientNetPackVisitor::visitSetAvailableArtifacts(SetAvailableArtifacts & pack)
{
if(pack.id < 0) //artifact merchants globally
if(!pack.id.hasValue()) //artifact merchants globally
{
callAllInterfaces(cl, &IGameEventsReceiver::availableArtifactsChanged, nullptr);
}

View File

@@ -315,14 +315,14 @@ void PlayerLocalState::serialize(JsonNode & dest) const
for (auto const * town : ownedTowns)
{
JsonNode record;
record["id"].Integer() = town->id;
record["id"].Integer() = town->id.getNum();
dest["towns"].Vector().push_back(record);
}
for (auto const * hero : wanderingHeroes)
{
JsonNode record;
record["id"].Integer() = hero->id;
record["id"].Integer() = hero->id.getNum();
if (vstd::contains(sleepingHeroes, hero))
record["sleeping"].Bool() = true;
@@ -340,7 +340,7 @@ void PlayerLocalState::serialize(JsonNode & dest) const
dest["spellbook"]["tabAdvmap"].Integer() = spellbookSettings.spellbookLastTabAdvmap;
if (currentSelection)
dest["currentSelection"].Integer() = currentSelection->id;
dest["currentSelection"].Integer() = currentSelection->id.getNum();
}
void PlayerLocalState::deserialize(const JsonNode & source)

View File

@@ -606,7 +606,7 @@ void AdventureMapInterface::onTileHovered(const int3 &targetPosition)
if(spellBeingCasted)
{
switch(spellBeingCasted->id)
switch(spellBeingCasted->id.toEnum())
{
case SpellID::SCUTTLE_BOAT:
if(isValidAdventureSpellTarget(targetPosition))

View File

@@ -55,18 +55,18 @@ TurnTimerWidget::TurnTimerWidget(const Point & position, PlayerColor player)
pos.w = 76;
pos.h += 20;
playerLabelsMain[player] = std::make_shared<CLabel>(pos.w / 2, pos.h - 10, FONT_BIG, ETextAlignment::CENTER, graphics->playerColors[player], "");
playerLabelsMain[player] = std::make_shared<CLabel>(pos.w / 2, pos.h - 10, FONT_BIG, ETextAlignment::CENTER, graphics->playerColors[player.getNum()], "");
if (timers.battleTimer != 0)
{
pos.h += 20;
playerLabelsBattle[player] = std::make_shared<CLabel>(pos.w / 2, pos.h - 10, FONT_BIG, ETextAlignment::CENTER, graphics->playerColors[player], "");
playerLabelsBattle[player] = std::make_shared<CLabel>(pos.w / 2, pos.h - 10, FONT_BIG, ETextAlignment::CENTER, graphics->playerColors[player.getNum()], "");
}
if (!timers.accumulatingUnitTimer && timers.unitTimer != 0)
{
pos.h += 20;
playerLabelsUnit[player] = std::make_shared<CLabel>(pos.w / 2, pos.h - 10, FONT_BIG, ETextAlignment::CENTER, graphics->playerColors[player], "");
playerLabelsUnit[player] = std::make_shared<CLabel>(pos.w / 2, pos.h - 10, FONT_BIG, ETextAlignment::CENTER, graphics->playerColors[player.getNum()], "");
}
updateTextLabel(player, GAME->interface()->cb->getPlayerTurnTime(player));
@@ -87,7 +87,7 @@ TurnTimerWidget::TurnTimerWidget(const Point & position, PlayerColor player)
continue;
pos.h += 20;
playerLabelsMain[player] = std::make_shared<CLabel>(pos.w / 2, pos.h - 10, FONT_BIG, ETextAlignment::CENTER, graphics->playerColors[player], "");
playerLabelsMain[player] = std::make_shared<CLabel>(pos.w / 2, pos.h - 10, FONT_BIG, ETextAlignment::CENTER, graphics->playerColors[player.getNum()], "");
updateTextLabel(player, GAME->interface()->cb->getPlayerTurnTime(player));
}

View File

@@ -631,7 +631,7 @@ void StackInfoBasicPanel::initializeData(const CStack * stack)
{
OBJECT_CONSTRUCTION;
icons.push_back(std::make_shared<CAnimImage>(AnimationPath::builtin("TWCRPORT"), stack->creatureId() + 2, 0, 10, 6));
icons.push_back(std::make_shared<CAnimImage>(AnimationPath::builtin("TWCRPORT"), stack->creatureId().getNum() + 2, 0, 10, 6));
labels.push_back(std::make_shared<CLabel>(10 + 58, 6 + 64, FONT_MEDIUM, ETextAlignment::BOTTOMRIGHT, Colors::WHITE, TextOperations::formatMetric(stack->getCount(), 4)));
int damageMultiplier = 1;
@@ -705,7 +705,7 @@ void StackInfoBasicPanel::initializeData(const CStack * stack)
int duration = spellBonuses->front()->turnsRemain;
icons.push_back(std::make_shared<CAnimImage>(AnimationPath::builtin("SpellInt"), effect + 1, 0, firstPos.x + offset.x * printed, firstPos.y + offset.y * printed));
icons.push_back(std::make_shared<CAnimImage>(AnimationPath::builtin("SpellInt"), effect.getNum() + 1, 0, firstPos.x + offset.x * printed, firstPos.y + offset.y * printed));
if(settings["general"]["enableUiEnhancements"].Bool())
labels.push_back(std::make_shared<CLabel>(firstPos.x + offset.x * printed + 46, firstPos.y + offset.y * printed + 36, EFonts::FONT_TINY, ETextAlignment::BOTTOMRIGHT, Colors::WHITE, std::to_string(duration)));
if(++printed >= 3 || (printed == 2 && spells.size() > 3)) // interface limit reached
@@ -837,7 +837,7 @@ BattleResultWindow::BattleResultWindow(const BattleResult & br, CPlayerInterface
int yPos = 344 + static_cast<int>(step) * 97;
for(auto & elem : br.casualties[step])
{
auto creature = LIBRARY->creatures()->getByIndex(elem.first);
auto creature = elem.first.toEntity(LIBRARY);
if (creature->getId() == CreatureID::ARROW_TOWERS )
continue; // do not show destroyed towers in battle results

View File

@@ -264,7 +264,7 @@ std::shared_ptr<IImage> BattleStacksController::getStackAmountBox(const CStack *
for(const auto & spellID : activeSpells)
{
auto positiveness = LIBRARY->spells()->getByIndex(spellID)->getPositiveness();
auto positiveness = spellID.toEntity(LIBRARY)->getPositiveness();
if(!boost::logic::indeterminate(positiveness))
{
if(positiveness)

View File

@@ -202,14 +202,14 @@ void CBonusSelection::createBonusesIcons()
}
}
assert(faction != -1);
assert(faction.hasValue());
BuildingID buildID;
if(getCampaign()->formatVCMI())
buildID = BuildingID(bonDescs[i].info1);
else
buildID = CBuildingHandler::campToERMU(bonDescs[i].info1, faction, std::set<BuildingID>());
picName = graphics->ERMUtoPicture[faction][buildID];
picName = graphics->ERMUtoPicture[faction.getNum()][buildID.getNum()];
picNumber = -1;
if(vstd::contains((*LIBRARY->townh)[faction]->town->buildings, buildID))
@@ -304,7 +304,7 @@ void CBonusSelection::createBonusesIcons()
}
case CampaignBonusType::HERO:
if(bonDescs[i].info2 == HeroTypeID::CAMP_RANDOM)
if(bonDescs[i].info2 == HeroTypeID::CAMP_RANDOM.getNum())
{
desc.appendLocalString(EMetaText::GENERAL_TXT, 720); // Start with random hero
picNumber = -1;
@@ -425,7 +425,7 @@ void CBonusSelection::startMap()
{
auto exitCb = []()
{
logGlobal->info("Starting scenario %d", static_cast<int>(GAME->server().campaignMap));
logGlobal->info("Starting scenario %d", GAME->server().campaignMap.getNum());
GAME->server().sendStartGame();
};

View File

@@ -822,7 +822,7 @@ OptionsTab::HandicapWindow::HandicapWindow()
INCOME = 1000,
GROWTH = 2000,
};
auto columns = std::vector<EGameResID>{EGameResID::GOLD, EGameResID::WOOD, EGameResID::MERCURY, EGameResID::ORE, EGameResID::SULFUR, EGameResID::CRYSTAL, EGameResID::GEMS, Columns::INCOME, Columns::GROWTH};
auto columns = std::vector<int>{EGameResID::GOLD, EGameResID::WOOD, EGameResID::MERCURY, EGameResID::ORE, EGameResID::SULFUR, EGameResID::CRYSTAL, EGameResID::GEMS, Columns::INCOME, Columns::GROWTH};
int i = 0;
for(auto & pInfo : SEL->getStartInfo()->playerInfos)
@@ -847,7 +847,7 @@ OptionsTab::HandicapWindow::HandicapWindow()
else if(isGrowth)
labels.push_back(std::make_shared<CLabel>(xPos, 38, FONT_TINY, ETextAlignment::TOPLEFT, Colors::WHITE, LIBRARY->generaltexth->translate("core.genrltxt.194")));
else
anim.push_back(std::make_shared<CAnimImage>(AnimationPath::builtin("SMALRES"), GameResID(resource), 0, 15 + xPos + (j == 0 ? 10 : 0), 35));
anim.push_back(std::make_shared<CAnimImage>(AnimationPath::builtin("SMALRES"), GameResID(resource).getNum(), 0, 15 + xPos + (j == 0 ? 10 : 0), 35));
}
auto area = Rect(xPos, 60 + i * 30, j == 0 ? 60 : 50, 16);

View File

@@ -229,7 +229,7 @@ void RandomMapTab::updateMapInfoByHost()
playerInfo.team = team;
playerInfo.hasMainTown = true;
playerInfo.generateHeroAtMainTown = true;
mapInfo->mapHeader->players[player.first] = playerInfo;
mapInfo->mapHeader->players[player.first.getNum()] = playerInfo;
vstd::erase(availableColors, player.first);
}

View File

@@ -152,7 +152,7 @@ void MapRendererTerrain::renderTile(IMapRendererContext & context, Canvas & targ
{
const TerrainTile & mapTile = context.getMapTile(coordinates);
int32_t terrainIndex = mapTile.getTerrainID();
int32_t terrainIndex = mapTile.getTerrainID().getNum();
int32_t imageIndex = mapTile.terView;
int32_t rotationIndex = mapTile.extTileFlags % 4;
@@ -194,7 +194,7 @@ void MapRendererRiver::renderTile(IMapRendererContext & context, Canvas & target
if(!mapTile.hasRiver())
return;
int32_t terrainIndex = mapTile.getRiverID();
int32_t terrainIndex = mapTile.getRiverID().getNum();
int32_t imageIndex = mapTile.riverDir;
int32_t rotationIndex = (mapTile.extTileFlags >> 2) % 4;
@@ -231,7 +231,7 @@ void MapRendererRoad::renderTile(IMapRendererContext & context, Canvas & target,
const TerrainTile & mapTileAbove = context.getMapTile(coordinatesAbove);
if(mapTileAbove.hasRoad())
{
int32_t terrainIndex = mapTileAbove.getRoadID();
int32_t terrainIndex = mapTileAbove.getRoadID().getNum();
int32_t imageIndex = mapTileAbove.roadDir;
int32_t rotationIndex = (mapTileAbove.extTileFlags >> 4) % 4;
@@ -243,7 +243,7 @@ void MapRendererRoad::renderTile(IMapRendererContext & context, Canvas & target,
const TerrainTile & mapTile = context.getMapTile(coordinates);
if(mapTile.hasRoad())
{
int32_t terrainIndex = mapTile.getRoadID();
int32_t terrainIndex = mapTile.getRoadID().getNum();
int32_t imageIndex = mapTile.roadDir;
int32_t rotationIndex = (mapTile.extTileFlags >> 4) % 4;

View File

@@ -129,7 +129,7 @@ void Graphics::setPlayerPalette(SDL_Palette * targetPalette, PlayerColor player)
if(player.isValidPlayer())
{
for(int i=0; i<32; ++i)
palette[i] = CSDL_Ext::toSDL(playerColorPalette[player][i]);
palette[i] = CSDL_Ext::toSDL(playerColorPalette[player.getNum()][i]);
}
else
{

View File

@@ -199,7 +199,7 @@ size_t CComponent::getIndex() const
case ComponentType::LUCK:
return std::clamp(data.value.value_or(0) + 3, 0, 6);
case ComponentType::BUILDING:
return data.subType.as<BuildingTypeUniqueID>().getBuilding();
return data.subType.as<BuildingTypeUniqueID>().getBuilding().getNum();
case ComponentType::HERO_PORTRAIT:
return LIBRARY->heroTypes()->getById(data.subType.as<HeroTypeID>())->getIconIndex();
case ComponentType::FLAG:

View File

@@ -39,7 +39,7 @@ void CreatureCostBox::createItems(TResources res)
TResources::nziterator iter(res);
while(iter.valid())
{
auto image = std::make_shared<CAnimImage>(AnimationPath::builtin("RESOURCE"), iter->resType);
auto image = std::make_shared<CAnimImage>(AnimationPath::builtin("RESOURCE"), iter->resType.getNum());
auto text = std::make_shared<CLabel>(15, 43, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE, "0");
resources.insert(std::make_pair(iter->resType, std::make_pair(text, image)));

View File

@@ -449,7 +449,7 @@ void CInteractableTownTooltip::init(const CGTownInstance * town)
OBJECT_CONSTRUCTION;
const InfoAboutTown townInfo = InfoAboutTown(town, true);
int townId = town->id;
ObjectInstanceID townId = town->id;
//order of icons in def: fort, citadel, castle, no fort
size_t fortIndex = townInfo.fortLevel ? townInfo.fortLevel - 1 : 3;

View File

@@ -189,7 +189,7 @@ CMarketBase::MarketShowcasesParams CAltarArtifacts::getShowcasesParams() const
return MarketShowcasesParams
{
std::nullopt,
ShowcaseParams {std::to_string(offerQty), LIBRARY->artifacts()->getByIndex(art->getTypeId())->getIconIndex()}
ShowcaseParams {std::to_string(offerQty), art->getType()->getIconIndex()}
};
return MarketShowcasesParams {std::nullopt, std::nullopt};
}

View File

@@ -91,7 +91,7 @@ void CArtifactsSelling::updateShowcases()
{
bidSelectedSlot->image->enable();
bidSelectedSlot->setID(art->getTypeId().num);
bidSelectedSlot->image->setFrame(LIBRARY->artifacts()->getByIndex(art->getTypeId())->getIconIndex());
bidSelectedSlot->image->setFrame(art->getTypeId().toEntity(LIBRARY)->getIconIndex());
bidSelectedSlot->subtitle->setText(std::to_string(bidQty));
}
else

View File

@@ -894,7 +894,7 @@ bool CCastleBuildings::buildingTryActivateCustomUI(BuildingID buildingToTest, Bu
}
else
{
switch(buildingToTest)
switch(buildingToTest.toEnum())
{
case BuildingID::MAGES_GUILD_1:
case BuildingID::MAGES_GUILD_2:
@@ -1065,7 +1065,7 @@ void CCastleBuildings::enterCastleGate(BuildingID building)
}
}
auto gateIcon = std::make_shared<CAnimImage>(town->getTown()->clientInfo.buildingsIcons, building);//will be deleted by selection window
auto gateIcon = std::make_shared<CAnimImage>(town->getTown()->clientInfo.buildingsIcons, building.getNum());//will be deleted by selection window
auto wnd = std::make_shared<CObjectListWindow>(availableTowns, gateIcon, LIBRARY->generaltexth->jktexts[40],
LIBRARY->generaltexth->jktexts[41], std::bind (&CCastleInterface::castleTeleport, GAME->interface()->castleInt, _1), 0, images);
wnd->onPopup = [availableTowns](int index) { CRClickPopup::createAndPush(GAME->interface()->cb->getObjInstance(ObjectInstanceID(availableTowns[index])), ENGINE->getCursorPosition()); };
@@ -1667,7 +1667,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->getTown()->clientInfo.buildingsIcons, building->bid, 0, 2, 2);
icon = std::make_shared<CAnimImage>(town->getTown()->clientInfo.buildingsIcons, building->bid.getNum(), 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);
@@ -1769,7 +1769,7 @@ CBuildWindow::CBuildWindow(const CGTownInstance *Town, const CBuilding * Buildin
{
OBJECT_CONSTRUCTION;
icon = std::make_shared<CAnimImage>(town->getTown()->clientInfo.buildingsIcons, building->bid, 0, 125, 50);
icon = std::make_shared<CAnimImage>(town->getTown()->clientInfo.buildingsIcons, building->bid.getNum(), 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);
@@ -2170,7 +2170,7 @@ CMageGuildScreen::Scroll::Scroll(Point position, const CSpell *Spell, ObjectInst
addUsedEvents(LCLICK | SHOW_POPUP | HOVER);
pos += position;
image = std::make_shared<CAnimImage>(AnimationPath::builtin("SPELLSCR"), spell->id);
image = std::make_shared<CAnimImage>(AnimationPath::builtin("SPELLSCR"), spell->id.getNum());
pos = image->pos;
}
@@ -2292,5 +2292,5 @@ CBlacksmithDialog::CBlacksmithDialog(bool possible, CreatureID creMachineID, Art
else
buy->block(true);
costIcon = std::make_shared<CAnimImage>(AnimationPath::builtin("RESOURCE"), GameResID(EGameResID::GOLD), 0, 148, 244);
costIcon = std::make_shared<CAnimImage>(AnimationPath::builtin("RESOURCE"), GameResID(EGameResID::GOLD).getNum(), 0, 148, 244);
}

View File

@@ -879,7 +879,7 @@ void CStackWindow::initBonusesList()
bonusInfo.imagePath = info->stackNode->bonusToGraphics(b);
bonusInfo.bonusSource = b->source;
if(b->sid.getNum() != info->stackNode->getId() && b->propagator && b->propagator->getPropagatorType() == CBonusSystemNode::HERO) // Shows bonus with "propagator":"HERO" only at creature with bonus
if(b->sid.as<CreatureID>() != info->stackNode->getId() && b->propagator && b->propagator->getPropagatorType() == CBonusSystemNode::HERO) // Shows bonus with "propagator":"HERO" only at creature with bonus
continue;
//if it's possible to give any description or image for this kind of bonus

View File

@@ -239,7 +239,7 @@ void CHeroWindow::update()
{
SecondarySkill skill = curHero->secSkills[g].first;
int level = curHero->getSecSkillLevel(skill);
std::string skillName = LIBRARY->skillh->getByIndex(skill)->getNameTranslated();
std::string skillName = skill.toEntity(LIBRARY)->getNameTranslated();
std::string skillValue = LIBRARY->generaltexth->levels[level-1];
secSkillNames[g]->setText(skillName);

View File

@@ -297,7 +297,7 @@ int InfoBoxHeroData::getSubID()
return index;
case HERO_SECONDARY_SKILL:
if(hero->secSkills.size() > index)
return hero->secSkills[index].first;
return hero->secSkills[index].first.getNum();
else
return 0;
case HERO_SPECIAL:
@@ -353,7 +353,7 @@ std::string InfoBoxHeroData::getHoverText()
if (hero->secSkills.size() > index)
{
std::string level = LIBRARY->generaltexth->levels[hero->secSkills[index].second-1];
std::string skill = LIBRARY->skillh->getByIndex(hero->secSkills[index].first)->getNameTranslated();
std::string skill = hero->secSkills[index].first.toEntity(LIBRARY)->getNameTranslated();
return boost::str(boost::format(LIBRARY->generaltexth->heroscrn[21]) % level % skill);
}
else

View File

@@ -48,9 +48,9 @@ CPuzzleWindow::CPuzzleWindow(const int3 & GrailPos, double discoveredRatio)
title = std::make_shared<CLabel>(700, 95, FONT_BIG, ETextAlignment::CENTER, Colors::YELLOW, LIBRARY->generaltexth->allTexts[463]);
resDataBar = std::make_shared<CResDataBar>(ImagePath::builtin("ARESBAR.bmp"), 3, 575, 32, 2, 85, 85);
int faction = GAME->interface()->cb->getStartInfo()->playerInfos.find(GAME->interface()->playerID)->second.castle;
FactionID faction = GAME->interface()->cb->getStartInfo()->playerInfos.find(GAME->interface()->playerID)->second.castle;
auto & puzzleMap = (*LIBRARY->townh)[faction]->puzzleMap;
auto & puzzleMap = faction.toFaction()->puzzleMap;
for(auto & elem : puzzleMap)
{

View File

@@ -101,7 +101,7 @@ void CQuestMinimap::update()
void CQuestMinimap::iconClicked()
{
if(currentQuest->obj)
if(currentQuest->obj.hasValue())
adventureInt->centerOnTile(currentQuest->getObject(GAME->interface()->cb.get())->visitablePos());
//moveAdvMapSelection();
}

View File

@@ -278,7 +278,7 @@ void CSpellWindow::processSpells()
spell->forEachSchool([&sitesPerOurTab](const SpellSchool & school, bool & stop)
{
++sitesPerOurTab[school];
++sitesPerOurTab[school.getNum()];
});
}
if(sitesPerTabAdv[4] % spellsPerPage == 0)
@@ -729,7 +729,7 @@ void CSpellWindow::SpellArea::setSpell(const CSpell * spell)
schoolLevel = owner->myHero->getSpellSchoolLevel(mySpell, &whichSchool);
auto spellCost = owner->myInt->cb->getSpellCost(mySpell, owner->myHero);
image->setFrame(mySpell->id);
image->setFrame(mySpell->id.getNum());
image->visible = true;
{
@@ -745,7 +745,7 @@ void CSpellWindow::SpellArea::setSpell(const CSpell * spell)
schoolBorder.reset();
if (owner->selectedTab >= 4)
{
if (whichSchool.getNum() != SpellSchool())
if (whichSchool.hasValue())
schoolBorder = std::make_shared<CAnimImage>(schoolBorders.at(whichSchool.getNum()), schoolLevel);
}
else

View File

@@ -439,9 +439,9 @@ CLevelWindow::CLevelWindow(const CGHeroInstance * hero, PrimarySkill pskill, std
levelTitle = std::make_shared<CLabel>(192, 162, FONT_MEDIUM, ETextAlignment::CENTER, Colors::WHITE, levelTitleText);
skillIcon = std::make_shared<CAnimImage>(AnimationPath::builtin("PSKIL42"), static_cast<int>(pskill), 0, 174, 190);
skillIcon = std::make_shared<CAnimImage>(AnimationPath::builtin("PSKIL42"), pskill.getNum(), 0, 174, 190);
skillValue = std::make_shared<CLabel>(192, 253, FONT_MEDIUM, ETextAlignment::CENTER, Colors::WHITE, LIBRARY->generaltexth->primarySkillNames[static_cast<int>(pskill)] + " +1");
skillValue = std::make_shared<CLabel>(192, 253, FONT_MEDIUM, ETextAlignment::CENTER, Colors::WHITE, LIBRARY->generaltexth->primarySkillNames[pskill.getNum()] + " +1");
}
void CLevelWindow::close()
@@ -765,8 +765,8 @@ CShipyardWindow::CShipyardWindow(const TResources & cost, int state, BoatId boat
goldCost = std::make_shared<CLabel>(118, 294, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE, goldValue);
woodCost = std::make_shared<CLabel>(212, 294, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE, woodValue);
goldPic = std::make_shared<CAnimImage>(AnimationPath::builtin("RESOURCE"), GameResID(EGameResID::GOLD), 0, 100, 244);
woodPic = std::make_shared<CAnimImage>(AnimationPath::builtin("RESOURCE"), GameResID(EGameResID::WOOD), 0, 196, 244);
goldPic = std::make_shared<CAnimImage>(AnimationPath::builtin("RESOURCE"), GameResID(EGameResID::GOLD).getNum(), 0, 100, 244);
woodPic = std::make_shared<CAnimImage>(AnimationPath::builtin("RESOURCE"), GameResID(EGameResID::WOOD).getNum(), 0, 196, 244);
quit = std::make_shared<CButton>(Point(224, 312), AnimationPath::builtin("ICANCEL"), CButton::tooltip(LIBRARY->generaltexth->allTexts[599]), std::bind(&CShipyardWindow::close, this), EShortcut::GLOBAL_CANCEL);
build = std::make_shared<CButton>(Point(42, 312), AnimationPath::builtin("IBUY30"), CButton::tooltip(LIBRARY->generaltexth->allTexts[598]), std::bind(&CShipyardWindow::close, this), EShortcut::GLOBAL_ACCEPT);
@@ -953,7 +953,7 @@ CUniversityWindow::CUniversityWindow(const CGHeroInstance * _hero, BuildingID bu
if(auto town = dynamic_cast<const CGTownInstance *>(_market))
{
auto faction = town->getTown()->faction->getId();
titlePic = std::make_shared<CAnimImage>((*LIBRARY->townh)[faction]->town->clientInfo.buildingsIcons, building);
titlePic = std::make_shared<CAnimImage>(faction.toFaction()->town->clientInfo.buildingsIcons, building.getNum());
}
else if(auto uni = dynamic_cast<const CGUniversity *>(_market); uni->appearance)
{
@@ -974,7 +974,7 @@ CUniversityWindow::CUniversityWindow(const CGHeroInstance * _hero, BuildingID bu
std::vector<TradeItemBuy> goods = market->availableItemsIds(EMarketMode::RESOURCE_SKILL);
for(int i=0; i<goods.size(); i++)//prepare clickable items
items.push_back(std::make_shared<CItem>(this, goods[i].as<SecondarySkill>(), 54+i*104, 234));
items.push_back(std::make_shared<CItem>(this, goods[i].as<SecondarySkill>().getNum(), 54+i*104, 234));
cancel = std::make_shared<CButton>(Point(200, 313), AnimationPath::builtin("IOKAY.DEF"), LIBRARY->generaltexth->zelp[632], [&](){ close(); }, EShortcut::GLOBAL_ACCEPT);
statusbar = CGStatusBar::create(std::make_shared<CPicture>(background->getSurface(), Rect(8, pos.h - 26, pos.w - 16, 19), 8, pos.h - 26));
@@ -1007,24 +1007,25 @@ CUnivConfirmWindow::CUnivConfirmWindow(CUniversityWindow * owner_, SecondarySkil
std::string text = LIBRARY->generaltexth->allTexts[608];
boost::replace_first(text, "%s", LIBRARY->generaltexth->levels[0]);
boost::replace_first(text, "%s", LIBRARY->skillh->getByIndex(SKILL)->getNameTranslated());
boost::replace_first(text, "%s", SKILL.toEntity(LIBRARY)->getNameTranslated());
boost::replace_first(text, "%d", "2000");
clerkSpeech = std::make_shared<CTextBox>(text, Rect(24, 129, 413, 70), 0, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE);
name = std::make_shared<CLabel>(230, 37, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE, LIBRARY->skillh->getByIndex(SKILL)->getNameTranslated());
icon = std::make_shared<CAnimImage>(AnimationPath::builtin("SECSKILL"), SKILL*3+3, 0, 211, 51);
name = std::make_shared<CLabel>(230, 37, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE, SKILL.toEntity(LIBRARY)->getNameTranslated());
icon = std::make_shared<CAnimImage>(AnimationPath::builtin("SECSKILL"), SKILL.getNum()*3+3, 0, 211, 51);
level = std::make_shared<CLabel>(230, 107, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE, LIBRARY->generaltexth->levels[1]);
costIcon = std::make_shared<CAnimImage>(AnimationPath::builtin("RESOURCE"), GameResID(EGameResID::GOLD), 0, 210, 210);
cost = std::make_shared<CLabel>(230, 267, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE, "2000");
std::string hoverText = LIBRARY->generaltexth->allTexts[609];
boost::replace_first(hoverText, "%s", LIBRARY->generaltexth->levels[0]+ " " + LIBRARY->skillh->getByIndex(SKILL)->getNameTranslated());
boost::replace_first(hoverText, "%s", LIBRARY->generaltexth->levels[0]+ " " + SKILL.toEntity(LIBRARY)->getNameTranslated());
text = LIBRARY->generaltexth->zelp[633].second;
boost::replace_first(text, "%s", LIBRARY->generaltexth->levels[0]);
boost::replace_first(text, "%s", LIBRARY->skillh->getByIndex(SKILL)->getNameTranslated());
boost::replace_first(text, "%s", SKILL.toEntity(LIBRARY)->getNameTranslated());
boost::replace_first(text, "%d", "2000");
confirm = std::make_shared<CButton>(Point(148, 299), AnimationPath::builtin("IBY6432.DEF"), CButton::tooltip(hoverText, text), [this, SKILL](){makeDeal(SKILL);}, EShortcut::GLOBAL_ACCEPT);
@@ -1230,7 +1231,7 @@ void CHillFortWindow::updateGarrisons()
else//free upgrade - print gold image and "Free" text
{
slotIcons[i][0]->visible = true;
slotIcons[i][0]->setFrame(GameResID(EGameResID::GOLD));
slotIcons[i][0]->setFrame(GameResID(EGameResID::GOLD).getNum());
slotLabels[i][0]->setText(LIBRARY->generaltexth->allTexts[344]);
}
}
@@ -1357,7 +1358,7 @@ CThievesGuildWindow::CThievesGuildWindow(const CGObjectInstance * _owner):
boost::algorithm::trim_if(text,boost::algorithm::is_any_of("\""));
if(settings["general"]["enableUiEnhancements"].Bool() && g >= 2 && g <= 4) // add icons instead of text (text is OH3 behavior)
{
auto addicon = [this, y](GameResID res, int x){ columnHeaderIcons.push_back(std::make_shared<CAnimImage>(AnimationPath::builtin("SMALRES"), res, 0, x, y - 10)); };
auto addicon = [this, y](GameResID res, int x){ columnHeaderIcons.push_back(std::make_shared<CAnimImage>(AnimationPath::builtin("SMALRES"), res.getNum(), 0, x, y - 10)); };
if(g == 2) // gold
addicon(GameResID::GOLD, 125);
else if(g == 3) // wood, ore

View File

@@ -160,6 +160,10 @@ public:
PrimarySkillsCache(const IBonusBearer * target);
const std::array<std::atomic<int32_t>, 4> & getSkills() const;
const std::atomic<int32_t> & getSkill(PrimarySkill id) const
{
return getSkills()[id.getNum()];
}
};
/// Cache that tracks values of spell school mastery in bonus system

View File

@@ -241,7 +241,7 @@ JsonNode CampaignHandler::writeScenarioToJson(const CampaignScenario & scenario)
JsonNode node;
node["map"].String() = scenario.mapName;
for(auto & g : scenario.preconditionRegions)
node["preconditions"].Vector().push_back(JsonNode(static_cast<ui32>(g)));
node["preconditions"].Vector().push_back(JsonNode(g.getNum()));
node["color"].Integer() = scenario.regionColor;
node["difficulty"].Integer() = scenario.difficulty;
node["regionText"].String() = scenario.regionText.toString();

View File

@@ -323,11 +323,13 @@ public:
//150-155 reserved for 8. creature with potential upgrades
DWELL_LVL_8=150, DWELL_LVL_8_UP=151, DWELL_LVL_8_UP2 = 152, DWELL_LVL_8_UP3 = 153, DWELL_LVL_8_UP4 = 154, DWELL_LVL_8_UP5 = 155,
};
};
private:
static std::array<std::array<Type, 8>, 6> getDwellings()
class DLL_LINKAGE BuildingID : public StaticIdentifierWithEnum<BuildingID, BuildingIDBase>
{
static const std::array<std::array<Type, 8>, 6> allDwellings = {{
static std::array<std::array<BuildingID, 8>, 6> getDwellings()
{
static const std::array<std::array<BuildingID, 8>, 6> allDwellings = {{
{ DWELL_LVL_1, DWELL_LVL_2, DWELL_LVL_3, DWELL_LVL_4, DWELL_LVL_5, DWELL_LVL_6, DWELL_LVL_7, DWELL_LVL_8 },
{ DWELL_LVL_1_UP, DWELL_LVL_2_UP, DWELL_LVL_3_UP, DWELL_LVL_4_UP, DWELL_LVL_5_UP, DWELL_LVL_6_UP, DWELL_LVL_7_UP, DWELL_LVL_8_UP },
{ DWELL_LVL_1_UP2, DWELL_LVL_2_UP2, DWELL_LVL_3_UP2, DWELL_LVL_4_UP2, DWELL_LVL_5_UP2, DWELL_LVL_6_UP2, DWELL_LVL_7_UP2, DWELL_LVL_8_UP2 },
@@ -339,65 +341,6 @@ private:
return allDwellings;
}
public:
static Type getDwellingFromLevel(int level, int upgradeIndex)
{
try
{
return getDwellings().at(upgradeIndex).at(level);
}
catch (const std::out_of_range &)
{
return Type::NONE;
}
}
static int getLevelFromDwelling(BuildingIDBase dwelling)
{
for (const auto & level : getDwellings())
{
auto it = std::find(level.begin(), level.end(), dwelling);
if (it != level.end())
return std::distance(level.begin(), it);
}
throw std::runtime_error("Call to getLevelFromDwelling with building '" + std::to_string(dwelling.num) +"' that is not dwelling!");
}
static int getUpgradedFromDwelling(BuildingIDBase dwelling)
{
const auto & dwellings = getDwellings();
for(int i = 0; i < dwellings.size(); i++)
{
if (vstd::contains(dwellings[i], dwelling))
return i;
}
throw std::runtime_error("Call to getUpgradedFromDwelling with building '" + std::to_string(dwelling.num) +"' that is not dwelling!");
}
static void advanceDwelling(BuildingIDBase & dwelling)
{
int level = getLevelFromDwelling(dwelling);
int upgrade = getUpgradedFromDwelling(dwelling);
dwelling.setNum(getDwellingFromLevel(level, upgrade + 1));
}
bool isDwelling() const
{
for (const auto & level : getDwellings())
{
if (vstd::contains(level, num))
return true;
}
return false;
}
};
class DLL_LINKAGE BuildingID : public StaticIdentifierWithEnum<BuildingID, BuildingIDBase>
{
public:
using StaticIdentifierWithEnum<BuildingID, BuildingIDBase>::StaticIdentifierWithEnum;
@@ -414,6 +357,76 @@ public:
static std::string encode(int32_t index);
static si32 decode(const std::string & identifier);
public:
int getMagesGuildLevel()
{
switch (toEnum())
{
case Type::MAGES_GUILD_1: return 1;
case Type::MAGES_GUILD_2: return 2;
case Type::MAGES_GUILD_3: return 3;
case Type::MAGES_GUILD_4: return 4;
case Type::MAGES_GUILD_5: return 5;
}
throw std::runtime_error("Call to getMageGuildLevel with building '" + std::to_string(getNum()) +"' that is not mages guild!");
}
static BuildingID getDwellingFromLevel(int level, int upgradeIndex)
{
try
{
return getDwellings().at(upgradeIndex).at(level);
}
catch (const std::out_of_range &)
{
return Type::NONE;
}
}
static int getLevelFromDwelling(BuildingID dwelling)
{
for (const auto & level : getDwellings())
{
auto it = std::find(level.begin(), level.end(), dwelling);
if (it != level.end())
return std::distance(level.begin(), it);
}
throw std::runtime_error("Call to getLevelFromDwelling with building '" + std::to_string(dwelling.num) +"' that is not dwelling!");
}
static int getUpgradedFromDwelling(BuildingID dwelling)
{
const auto & dwellings = getDwellings();
for(int i = 0; i < dwellings.size(); i++)
{
if (vstd::contains(dwellings[i], dwelling))
return i;
}
throw std::runtime_error("Call to getUpgradedFromDwelling with building '" + std::to_string(dwelling.num) +"' that is not dwelling!");
}
static void advanceDwelling(BuildingID & dwelling)
{
int level = getLevelFromDwelling(dwelling);
int upgrade = getUpgradedFromDwelling(dwelling);
dwelling = getDwellingFromLevel(level, upgrade + 1);
}
bool isDwelling() const
{
for (const auto & level : getDwellings())
{
if (vstd::contains(level, BuildingID(num)))
return true;
}
return false;
}
};
class MapObjectBaseID : public IdentifierBase

View File

@@ -221,7 +221,7 @@ void CGameStateCampaign::placeCampaignHeroes()
if(it != gameState->scenarioOps->playerInfos.end())
{
HeroTypeID heroTypeId = HeroTypeID(campaignBonus->info2);
if(heroTypeId.getNum() == HeroTypeID::CAMP_RANDOM) // random bonus hero
if(heroTypeId == HeroTypeID::CAMP_RANDOM) // random bonus hero
{
heroTypeId = gameState->pickUnusedHeroTypeRandomly(playerColor);
}
@@ -519,7 +519,7 @@ void CGameStateCampaign::generateCampaignHeroesToReplace()
void CGameStateCampaign::initHeroes()
{
auto chosenBonus = currentBonus();
if (chosenBonus && chosenBonus->isBonusForHero() && chosenBonus->info1 != HeroTypeID::CAMP_GENERATED) //exclude generated heroes
if (chosenBonus && chosenBonus->isBonusForHero() && chosenBonus->info1 != HeroTypeID::CAMP_GENERATED.getNum()) //exclude generated heroes
{
//find human player
PlayerColor humanPlayer=PlayerColor::NEUTRAL;
@@ -535,7 +535,7 @@ void CGameStateCampaign::initHeroes()
const auto & heroes = gameState->players.at(humanPlayer).getHeroes();
if (chosenBonus->info1 == HeroTypeID::CAMP_STRONGEST) //most powerful
if (chosenBonus->info1 == HeroTypeID::CAMP_STRONGEST.getNum()) //most powerful
{
int maxB = -1;
for (int b=0; b<heroes.size(); ++b)

View File

@@ -81,7 +81,7 @@ void IVisualLogBuilder::addText(int3 tile, const std::string & text, PlayerColor
{
std::optional<ColorRGBA> rgbColor;
switch(background)
switch(background.getNum())
{
case 0:
rgbColor = ColorRGBA(255, 0, 0);

View File

@@ -721,13 +721,13 @@ void CGHeroInstance::setPropertyDer(ObjProperty what, ObjPropertyID identifier)
int CGHeroInstance::getPrimSkillLevel(PrimarySkill id) const
{
return primarySkills.getSkills()[id];
return primarySkills.getSkill(id);
}
double CGHeroInstance::getFightingStrength() const
{
const auto & skillValues = primarySkills.getSkills();
return sqrt((1.0 + 0.05*skillValues[PrimarySkill::ATTACK]) * (1.0 + 0.05*skillValues[PrimarySkill::DEFENSE]));
return sqrt((1.0 + 0.05*skillValues[PrimarySkill::ATTACK.getNum()]) * (1.0 + 0.05*skillValues[PrimarySkill::DEFENSE.getNum()]));
}
double CGHeroInstance::getMagicStrength() const
@@ -746,7 +746,7 @@ double CGHeroInstance::getMagicStrength() const
}
if (!atLeastOneCombatSpell)
return 1;
return sqrt((1.0 + 0.05*skillValues[PrimarySkill::KNOWLEDGE] * mana / manaLimit()) * (1.0 + 0.05*skillValues[PrimarySkill::SPELL_POWER] * mana / manaLimit()));
return sqrt((1.0 + 0.05*skillValues[PrimarySkill::KNOWLEDGE.getNum()] * mana / manaLimit()) * (1.0 + 0.05*skillValues[PrimarySkill::SPELL_POWER.getNum()] * mana / manaLimit()));
}
double CGHeroInstance::getHeroStrength() const
@@ -1976,7 +1976,7 @@ const IOwnableObject * CGHeroInstance::asOwnable() const
int CGHeroInstance::getBasePrimarySkillValue(PrimarySkill which) const
{
std::string cachingStr = "CGHeroInstance::getBasePrimarySkillValue" + std::to_string(static_cast<int>(which));
std::string cachingStr = "CGHeroInstance::getBasePrimarySkillValue" + std::to_string(which.getNum());
auto selector = Selector::typeSubtype(BonusType::PRIMARY_SKILL, BonusSubtypeID(which)).And(Selector::sourceType()(BonusSource::HERO_BASE_SKILL));
auto minSkillValue = LIBRARY->engineSettings()->getVectorValue(EGameSettings::HEROES_MINIMAL_PRIMARY_SKILLS, which.getNum());
return std::max(valOfBonuses(selector, cachingStr), minSkillValue);

View File

@@ -106,7 +106,7 @@ void TownRewardableBuildingInstance::newTurn(vstd::RNG & rand) const
if(configuration.resetParameters.visitors)
{
cb->setObjPropertyValue(town->id, ObjProperty::STRUCTURE_CLEAR_VISITORS, getBuildingType());
cb->setObjPropertyValue(town->id, ObjProperty::STRUCTURE_CLEAR_VISITORS, getBuildingType().getNum());
}
}
}
@@ -212,7 +212,7 @@ bool TownRewardableBuildingInstance::wasVisited(PlayerColor player) const
void TownRewardableBuildingInstance::markAsVisited(const CGHeroInstance * hero) const
{
town->addHeroToStructureVisitors(hero, getBuildingType());
town->addHeroToStructureVisitors(hero, getBuildingType().getNum());
}
void TownRewardableBuildingInstance::markAsScouted(const CGHeroInstance * hero) const

View File

@@ -164,7 +164,7 @@ EDiggingStatus TerrainTile::getDiggingStatus(const bool excludeTop) const
return EDiggingStatus::WRONG_TERRAIN;
int allowedBlocked = excludeTop ? 1 : 0;
if(blockingObjects.size() > allowedBlocked || topVisitableObj(excludeTop))
if(blockingObjects.size() > allowedBlocked || topVisitableObj(excludeTop).hasValue())
return EDiggingStatus::TILE_OCCUPIED;
else
return EDiggingStatus::CAN_DIG;

View File

@@ -464,9 +464,9 @@ void CZonePlacer::prepareZones(TZoneMap &zones, TZoneVector &zonesVector, const
auto player = PlayerColor(*owner - 1);
auto playerSettings = map.getMapGenOptions().getPlayersSettings();
FactionID faction = FactionID::RANDOM;
if (playerSettings.size() > player)
if (playerSettings.size() > player.getNum())
{
faction = std::next(playerSettings.begin(), player)->second.getStartingTown();
faction = std::next(playerSettings.begin(), player.getNum())->second.getStartingTown();
}
else
{

View File

@@ -767,7 +767,7 @@ rmg::Object TreasurePlacer::constructTreasurePile(const std::vector<ObjectInfo*>
if (templates.empty())
{
throw rmgException(boost::str(boost::format("Did not find template for object (%d,%d) at %s") % object->ID % object->subID % zone.getTerrainType().encode(zone.getTerrainType())));
throw rmgException(boost::str(boost::format("Did not find template for object (%d,%d) at %s") % object->ID.getNum() % object->subID.getNum() % zone.getTerrainType().encode(zone.getTerrainType().getNum())));
}
object->appearance = *RandomGeneratorUtil::nextItem(templates, zone.getRand());

View File

@@ -953,10 +953,10 @@ bool CVCMIServer::canUseThisHero(PlayerColor player, HeroTypeID ID)
if (!ID.hasValue())
return false;
if (ID >= LIBRARY->heroh->size())
if (ID.getNum() >= LIBRARY->heroh->size())
return false;
if (si->playerInfos[player].castle != LIBRARY->heroh->objects[ID]->heroClass->faction)
if (si->playerInfos[player].castle != ID.toHeroType()->heroClass->faction)
return false;
if (vstd::contains(getUsedHeroes(), ID))
@@ -979,7 +979,7 @@ std::vector<HeroTypeID> CVCMIServer::getUsedHeroes()
{
const auto & heroes = getPlayerInfo(p.first).heroesNames;
for(auto & hero : heroes)
if(hero.heroId >= 0) //in VCMI map format heroId = -1 means random hero
if(hero.heroId.hasValue())
heroIds.push_back(hero.heroId);
if(p.second.hero != HeroTypeID::RANDOM)

View File

@@ -217,7 +217,7 @@ void BattleResultProcessor::endBattle(const CBattleInfoCallback & battle)
r.exp[BattleSide::DEFENDER] = 0;
for (auto i = r.casualties[battle.otherSide(r.winner)].begin(); i!=r.casualties[battle.otherSide(r.winner)].end(); i++)
{
r.exp[r.winner] += LIBRARY->creh->objects.at(i->first)->valOfBonuses(BonusType::STACK_HEALTH) * i->second;
r.exp[r.winner] += i->first.toCreature()->valOfBonuses(BonusType::STACK_HEALTH) * i->second;
}
};

View File

@@ -257,7 +257,7 @@ ResourceSet NewTurnProcessor::generatePlayerIncome(PlayerColor playerID, bool ne
// Distribute weekly bonuses over 7 days, depending on the current day of the week
for (GameResID i : GameResID::ALL_RESOURCES())
{
const std::string & name = GameConstants::RESOURCE_NAMES[i];
const std::string & name = GameConstants::RESOURCE_NAMES[i.getNum()];
int64_t weeklyBonus = difficultyConfig[name].Integer();
int64_t dayOfWeek = gameHandler->gameState().getDate(Date::DAY_OF_WEEK);
int64_t dailyIncome = incomeHandicapped[i];
@@ -552,8 +552,7 @@ std::tuple<EWeekType, CreatureID> NewTurnProcessor::pickWeekType(bool newMonth)
do
{
newMonster.second = LIBRARY->creh->pickRandomMonster(gameHandler->getRandomGenerator());
} while (LIBRARY->creh->objects[newMonster.second] &&
(*LIBRARY->townh)[LIBRARY->creatures()->getById(newMonster.second)->getFactionID()]->town == nullptr); // find first non neutral creature
} while (newMonster.second.toEntity(LIBRARY)->getFactionID().toFaction()->town == nullptr); // find first non neutral creature
return { EWeekType::BONUS_GROWTH, newMonster.second};
}

View File

@@ -81,11 +81,13 @@ bool CGarrisonDialogQuery::blocksPack(const CPackForServer * pack) const
if(auto arts = dynamic_cast<const ExchangeArtifacts*>(pack))
{
if(auto id1 = arts->src.artHolder)
auto id1 = arts->src.artHolder;
if(id1.hasValue())
if(!vstd::contains(ourIds, id1))
return true;
if(auto id2 = arts->dst.artHolder)
auto id2 = arts->dst.artHolder;
if(id2.hasValue())
if(!vstd::contains(ourIds, id2))
return true;
return false;
@@ -101,7 +103,8 @@ bool CGarrisonDialogQuery::blocksPack(const CPackForServer * pack) const
if(auto art = dynamic_cast<const EraseArtifactByClient*>(pack))
{
if(auto id = art->al.artHolder)
auto id = art->al.artHolder;
if(id.hasValue())
return !vstd::contains(ourIds, id);
}

View File

@@ -363,7 +363,7 @@ TEST_P(HealApplyTest, DISABLED_Heals)
mechanicsMock.caster = &actualCaster;
EXPECT_CALL(mechanicsMock, getEffectValue()).WillRepeatedly(Return(effectValue));
EXPECT_CALL(mechanicsMock, applySpellBonus(Eq(effectValue), Eq(&targetUnit))).WillRepeatedly(Return(effectValue));
EXPECT_CALL(actualCaster, creatureIndex()).WillRepeatedly(Return(CreatureID(unitId)));
EXPECT_CALL(actualCaster, creatureId()).WillRepeatedly(Return(CreatureID(unitId)));
EXPECT_CALL(actualCaster, getHeroCaster()).WillRepeatedly(Return(nullptr));
GTEST_ASSERT_EQ(targetUnitState->getAvailableHealth(), unitAmount * unitHP / 2 + 1);