From 11b237a23cc24857ac6a00eeaae64fae4c279f90 Mon Sep 17 00:00:00 2001 From: Konstantin Date: Wed, 5 Apr 2023 03:26:29 +0300 Subject: [PATCH] vcmi: massive refactoring v1 --- AI/BattleAI/BattleAI.cpp | 2 +- AI/BattleAI/StackWithBonuses.cpp | 2 +- AI/Nullkiller/AIGateway.cpp | 12 +- AI/Nullkiller/AIUtility.cpp | 12 +- AI/Nullkiller/AIUtility.h | 2 +- AI/Nullkiller/Analyzers/ArmyManager.cpp | 39 ++- AI/Nullkiller/Analyzers/BuildAnalyzer.cpp | 22 +- AI/Nullkiller/Behaviors/BuildingBehavior.cpp | 2 +- AI/Nullkiller/Behaviors/DefenceBehavior.cpp | 2 +- .../Behaviors/RecruitHeroBehavior.cpp | 2 +- AI/Nullkiller/Behaviors/StartupBehavior.cpp | 2 +- AI/Nullkiller/Engine/FuzzyEngines.cpp | 8 +- AI/Nullkiller/Engine/Nullkiller.h | 2 +- AI/Nullkiller/Engine/PriorityEvaluator.cpp | 41 +-- AI/Nullkiller/Goals/BuyArmy.cpp | 4 +- AI/Nullkiller/Goals/CompleteQuest.cpp | 2 +- AI/Nullkiller/Goals/GatherArmy.cpp | 2 +- AI/Nullkiller/Goals/Trade.h | 4 +- AI/Nullkiller/Markers/ArmyUpgrade.cpp | 2 +- AI/Nullkiller/Pathfinding/Actors.cpp | 12 +- AI/StupidAI/StupidAI.cpp | 2 +- AI/VCAI/AIUtility.cpp | 4 +- AI/VCAI/AIUtility.h | 2 +- AI/VCAI/ArmyManager.cpp | 15 +- AI/VCAI/FuzzyEngines.cpp | 8 +- AI/VCAI/Goals/BuyArmy.cpp | 2 +- AI/VCAI/Goals/CollectRes.cpp | 22 +- AI/VCAI/Goals/CollectRes.h | 4 +- AI/VCAI/Goals/CompleteQuest.cpp | 4 +- AI/VCAI/Goals/GatherArmy.cpp | 2 +- AI/VCAI/Goals/GatherTroops.cpp | 16 +- AI/VCAI/Goals/RecruitHero.cpp | 2 +- AI/VCAI/Goals/Trade.h | 4 +- AI/VCAI/Goals/Win.cpp | 2 +- AI/VCAI/MapObjectsEvaluator.cpp | 4 +- AI/VCAI/ResourceManager.cpp | 32 +- AI/VCAI/VCAI.cpp | 22 +- Global.h | 2 +- client/Client.h | 2 +- client/adventureMap/CResDataBar.cpp | 2 +- client/battle/BattleAnimationClasses.cpp | 2 +- client/battle/BattleInterfaceClasses.cpp | 4 +- client/battle/BattleProjectileController.cpp | 2 +- client/battle/BattleStacksController.cpp | 2 +- client/battle/BattleWindow.cpp | 2 +- client/lobby/OptionsTab.cpp | 44 +-- client/widgets/CreatureCostBox.h | 2 +- client/widgets/MiscWidgets.cpp | 12 +- client/windows/CCastleInterface.cpp | 15 +- client/windows/CCreatureWindow.cpp | 4 +- client/windows/CKingdomInterface.cpp | 12 +- client/windows/CTradeWindow.cpp | 12 +- client/windows/CreaturePurchaseCard.cpp | 8 +- client/windows/GUIClasses.cpp | 36 +- client/windows/QuickRecruitmentWindow.cpp | 8 +- include/vcmi/Creature.h | 7 +- include/vcmi/Entity.h | 10 +- lib/CArtHandler.cpp | 2 +- lib/CArtHandler.h | 2 +- lib/CCreatureHandler.cpp | 30 +- lib/CCreatureHandler.h | 24 +- lib/CCreatureSet.cpp | 18 +- lib/CCreatureSet.h | 4 +- lib/CGameInfoCallback.cpp | 12 +- lib/CGameInfoCallback.h | 8 +- lib/CGameState.cpp | 62 ++-- lib/CGameStateFwd.h | 2 +- lib/CHeroHandler.cpp | 2 +- lib/CPlayerState.cpp | 2 +- lib/CPlayerState.h | 2 +- lib/CStack.cpp | 4 +- lib/CTownHandler.cpp | 25 +- lib/CTownHandler.h | 2 +- lib/GameConstants.h | 10 + lib/HeroBonus.cpp | 6 +- lib/IGameCallback.h | 2 +- lib/NetPacksLib.cpp | 4 +- lib/ResourceSet.cpp | 74 ++-- lib/ResourceSet.h | 330 +++++++++--------- lib/battle/BattleInfo.cpp | 2 +- lib/battle/BattleInfo.h | 2 +- lib/battle/BattleProxy.cpp | 4 +- lib/battle/BattleProxy.h | 2 +- lib/battle/BattleStateInfoForRetreat.cpp | 2 +- lib/battle/CBattleInfoCallback.cpp | 4 +- lib/battle/CBattleInfoEssentials.cpp | 4 +- lib/battle/CBattleInfoEssentials.h | 2 +- lib/battle/CUnitState.cpp | 8 +- lib/battle/DamageCalculator.cpp | 2 +- lib/battle/IBattleInfoCallback.h | 4 +- lib/battle/IBattleState.h | 4 +- lib/mapObjects/CArmedInstance.cpp | 2 +- lib/mapObjects/CBank.cpp | 8 +- lib/mapObjects/CGHeroInstance.cpp | 10 +- lib/mapObjects/CGMarket.cpp | 4 +- lib/mapObjects/CGTownInstance.cpp | 30 +- lib/mapObjects/CObjectHandler.cpp | 4 +- lib/mapObjects/CQuest.cpp | 6 +- lib/mapObjects/CQuest.h | 3 +- lib/mapObjects/CRewardableObject.cpp | 2 +- lib/mapObjects/CommonConstructors.cpp | 26 +- lib/mapObjects/CommonConstructors.h | 2 +- lib/mapObjects/MiscObjects.cpp | 46 +-- lib/mapObjects/MiscObjects.h | 2 +- lib/mapping/MapFormatH3M.cpp | 6 +- lib/rmg/MinePlacer.cpp | 5 +- lib/rmg/ObjectManager.cpp | 12 +- lib/rmg/TreasurePlacer.cpp | 26 +- lib/serializer/CSerializer.cpp | 2 +- mapeditor/inspector/inspector.cpp | 20 +- mapeditor/inspector/inspector.h | 2 +- mapeditor/inspector/questwidget.cpp | 1 - mapeditor/inspector/rewardswidget.cpp | 4 +- scripting/lua/api/Artifact.cpp | 2 +- scripting/lua/api/Creature.cpp | 4 +- scripting/lua/api/Creature.h | 4 +- scripting/lua/api/Player.cpp | 2 +- scripting/lua/api/netpacks/SetResources.cpp | 4 +- scripts/lib/erm/MA.lua | 2 +- server/CGameHandler.cpp | 84 ++--- server/CGameHandler.h | 10 +- server/NetPacksServer.cpp | 8 +- test/entity/CCreatureTest.cpp | 2 +- test/erm/ERM_MA.cpp | 8 +- test/game/CGameStateTest.cpp | 4 +- test/mock/mock_Creature.h | 2 +- test/mock/mock_IGameCallback.h | 2 +- test/mock/mock_battle_IBattleState.h | 2 +- test/vcai/ResurceManagerTest.cpp | 24 +- 129 files changed, 803 insertions(+), 762 deletions(-) diff --git a/AI/BattleAI/BattleAI.cpp b/AI/BattleAI/BattleAI.cpp index 4ea5470b2..595d88912 100644 --- a/AI/BattleAI/BattleAI.cpp +++ b/AI/BattleAI/BattleAI.cpp @@ -101,7 +101,7 @@ BattleAction CBattleAI::activeStack( const CStack * stack ) try { - if(stack->type->idNumber == CreatureID::CATAPULT) + if(stack->type->getId() == CreatureID::CATAPULT) return useCatapult(stack); if(stack->hasBonusOfType(Bonus::SIEGE_WEAPON) && stack->hasBonusOfType(Bonus::HEALER)) { diff --git a/AI/BattleAI/StackWithBonuses.cpp b/AI/BattleAI/StackWithBonuses.cpp index 78fcdbb1b..6c0cfaf0d 100644 --- a/AI/BattleAI/StackWithBonuses.cpp +++ b/AI/BattleAI/StackWithBonuses.cpp @@ -435,7 +435,7 @@ int64_t HypotheticBattle::getActualDamage(const DamageRange & damage, int32_t at int64_t HypotheticBattle::getTreeVersion() const { - return getBattleNode()->getTreeVersion() + bonusTreeVersion; + return getBonusBearer()->getTreeVersion() + bonusTreeVersion; } #if SCRIPTING_ENABLED diff --git a/AI/Nullkiller/AIGateway.cpp b/AI/Nullkiller/AIGateway.cpp index 516a33514..3794e0c34 100644 --- a/AI/Nullkiller/AIGateway.cpp +++ b/AI/Nullkiller/AIGateway.cpp @@ -1053,7 +1053,7 @@ void AIGateway::recruitCreatures(const CGDwelling * d, const CArmedInstance * re int count = d->creatures[i].first; CreatureID creID = d->creatures[i].second.back(); - vstd::amin(count, cb->getResourceAmount() / VLC->creh->objects[creID]->cost); + vstd::amin(count, cb->getResourceAmount() / creID.toCreature()->getFullRecruitCost()); if(count > 0) cb->recruitCreatures(d, recruiter, creID, count, i); } @@ -1068,7 +1068,7 @@ bool AIGateway::canRecruitAnyHero(const CGTownInstance * t) const if(!t || !townHasFreeTavern(t)) return false; - if(cb->getResourceAmount(Res::GOLD) < GameConstants::HERO_GOLD_COST) //TODO: use ResourceManager + if(cb->getResourceAmount(EGameResID::GOLD) < GameConstants::HERO_GOLD_COST) //TODO: use ResourceManager return false; if(cb->getHeroesInfo().size() >= ALLOWED_ROAMING_HEROES) return false; @@ -1390,7 +1390,7 @@ void AIGateway::tryRealize(Goals::DigAtTile & g) void AIGateway::tryRealize(Goals::Trade & g) //trade { - if(cb->getResourceAmount((Res::ERes)g.resID) >= g.value) //goal is already fulfilled. Why we need this check, anyway? + if(cb->getResourceAmount(GameResID(g.resID)) >= g.value) //goal is already fulfilled. Why we need this check, anyway? throw goalFulfilledException(sptr(g)); int accquiredResources = 0; @@ -1399,10 +1399,10 @@ void AIGateway::tryRealize(Goals::Trade & g) //trade if(const IMarket * m = IMarket::castFrom(obj, false)) { auto freeRes = cb->getResourceAmount(); //trade only resources which are not reserved - for(auto it = Res::ResourceSet::nziterator(freeRes); it.valid(); it++) + for(auto it = ResourceSet::nziterator(freeRes); it.valid(); it++) { auto res = it->resType; - if(res == g.resID) //sell any other resource + if(res.getNum() == g.resID) //sell any other resource continue; int toGive, toGet; @@ -1415,7 +1415,7 @@ void AIGateway::tryRealize(Goals::Trade & g) //trade accquiredResources = static_cast(toGet * (it->resVal / toGive)); logAi->debug("Traded %d of %s for %d of %s at %s", toGive, res, accquiredResources, g.resID, obj->getObjectName()); } - if (cb->getResourceAmount((Res::ERes)g.resID) >= g.value) + if (cb->getResourceAmount(GameResID(g.resID))) throw goalFulfilledException(sptr(g)); //we traded all we needed } diff --git a/AI/Nullkiller/AIUtility.cpp b/AI/Nullkiller/AIUtility.cpp index 965eb0bd6..e3f683a09 100644 --- a/AI/Nullkiller/AIUtility.cpp +++ b/AI/Nullkiller/AIUtility.cpp @@ -20,6 +20,8 @@ #include "../../lib/GameSettings.h" +#include + namespace NKAI { @@ -278,8 +280,8 @@ creInfo infoFromDC(const dwellingContent & dc) ci.creID = dc.second.size() ? dc.second.back() : CreatureID(-1); //should never be accessed if (ci.creID != -1) { - ci.cre = VLC->creh->objects[ci.creID].get(); - ci.level = ci.cre->level; //this is cretaure tier, while tryRealize expects dwelling level. Ignore. + ci.cre = VLC->creatures()->getById(ci.creID); + ci.level = ci.cre->getLevel(); //this is creature tier, while tryRealize expects dwelling level. Ignore. } else { @@ -398,7 +400,7 @@ bool shouldVisit(const Nullkiller * ai, const CGHeroInstance * h, const CGObject { if(level.first && h->getSlotFor(CreatureID(c)) != SlotID() - && ai->cb->getResourceAmount().canAfford(c.toCreature()->cost)) + && ai->cb->getResourceAmount().canAfford(c.toCreature()->getFullRecruitCost())) { return true; } @@ -411,7 +413,7 @@ bool shouldVisit(const Nullkiller * ai, const CGHeroInstance * h, const CGObject { for(auto slot : h->Slots()) { - if(slot.second->type->upgrades.size()) + if(slot.second->type->hasUpgrades()) return true; //TODO: check price? } return false; @@ -438,7 +440,7 @@ bool shouldVisit(const Nullkiller * ai, const CGHeroInstance * h, const CGObject return false; TResources myRes = ai->getFreeResources(); - if(myRes[Res::GOLD] < 2000 || myRes[Res::GEMS] < 10) + if(myRes[EGameResID::GOLD] < 2000 || myRes[EGameResID::GEMS] < 10) return false; break; } diff --git a/AI/Nullkiller/AIUtility.h b/AI/Nullkiller/AIUtility.h index 9d4db7f67..d06da7958 100644 --- a/AI/Nullkiller/AIUtility.h +++ b/AI/Nullkiller/AIUtility.h @@ -161,7 +161,7 @@ struct creInfo { int count; CreatureID creID; - CCreature * cre; + const Creature * cre; int level; }; creInfo infoFromDC(const dwellingContent & dc); diff --git a/AI/Nullkiller/Analyzers/ArmyManager.cpp b/AI/Nullkiller/Analyzers/ArmyManager.cpp index 05c1ecc68..60093d6e0 100644 --- a/AI/Nullkiller/Analyzers/ArmyManager.cpp +++ b/AI/Nullkiller/Analyzers/ArmyManager.cpp @@ -28,8 +28,8 @@ public: StackUpgradeInfo(CreatureID initial, CreatureID upgraded, int count) :initialCreature(initial), upgradedCreature(upgraded), count(count) { - cost = (upgradedCreature.toCreature()->cost - initialCreature.toCreature()->cost) * count; - upgradeValue = (upgradedCreature.toCreature()->AIValue - initialCreature.toCreature()->AIValue) * count; + cost = (upgradedCreature.toCreature()->getFullRecruitCost() - initialCreature.toCreature()->getFullRecruitCost()) * count; + upgradeValue = (upgradedCreature.toCreature()->getAIValue() - initialCreature.toCreature()->getAIValue()) * count; } }; @@ -50,9 +50,10 @@ std::vector ArmyManager::getSortedSlots(const CCreatureSet * target, c { for(auto & i : armyPtr->Slots()) { - auto & slotInfp = creToPower[i.second->type]; + auto cre = dynamic_cast(i.second->type); + auto & slotInfp = creToPower[cre]; - slotInfp.creature = i.second->type; + slotInfp.creature = cre; slotInfp.power += i.second->getPower(); slotInfp.count += i.second->count; } @@ -73,8 +74,8 @@ std::vector::iterator ArmyManager::getWeakestCreature(std::vector bool { - if(left.creature->level != right.creature->level) - return left.creature->level < right.creature->level; + if(left.creature->getLevel() != right.creature->getLevel()) + return left.creature->getLevel() < right.creature->getLevel(); return left.creature->Speed() > right.creature->Speed(); }); @@ -99,7 +100,7 @@ std::vector ArmyManager::getBestArmy(const IBonusBearer * armyCarrier, for(auto & slot : sortedSlots) { - alignmentMap[slot.creature->faction] += slot.power; + alignmentMap[slot.creature->getFactionIndex()] += slot.power; } std::set allowedFactions; @@ -133,13 +134,13 @@ std::vector ArmyManager::getBestArmy(const IBonusBearer * armyCarrier, for(auto & slot : sortedSlots) { - if(vstd::contains(allowedFactions, slot.creature->faction)) + if(vstd::contains(allowedFactions, slot.creature->getFactionIndex())) { auto slotID = newArmyInstance.getSlotFor(slot.creature); if(slotID.validSlot()) { - newArmyInstance.setCreature(slotID, slot.creature->idNumber, slot.count); + newArmyInstance.setCreature(slotID, slot.creature->getId(), slot.count); newArmy.push_back(slot); } } @@ -217,7 +218,7 @@ std::shared_ptr ArmyManager::getArmyAvailableToBuyAsCCreatureSet( if(!ci.count || ci.creID == -1) continue; - vstd::amin(ci.count, availableRes / ci.cre->cost); //max count we can afford + vstd::amin(ci.count, availableRes / ci.cre->getFullRecruitCost()); //max count we can afford if(!ci.count) continue; @@ -228,7 +229,7 @@ std::shared_ptr ArmyManager::getArmyAvailableToBuyAsCCreatureSet( break; army->setCreature(dst, ci.creID, ci.count); - availableRes -= ci.cre->cost * ci.count; + availableRes -= ci.cre->getFullRecruitCost() * ci.count; } return army; @@ -244,7 +245,7 @@ ui64 ArmyManager::howManyReinforcementsCanBuy( for(const creInfo & ci : army) { - aivalue += ci.count * ci.cre->AIValue; + aivalue += ci.count * ci.cre->getAIValue(); } return aivalue; @@ -279,14 +280,14 @@ std::vector ArmyManager::getArmyAvailableToBuy( freeHeroSlots--; //new slot will be occupied } - vstd::amin(ci.count, availableRes / ci.cre->cost); //max count we can afford + vstd::amin(ci.count, availableRes / ci.cre->getFullRecruitCost()); //max count we can afford if(!ci.count) continue; ci.level = i; //this is important for Dungeon Summoning Portal creaturesInDwellings.push_back(ci); - availableRes -= ci.cre->cost * ci.count; + availableRes -= ci.cre->getFullRecruitCost() * ci.count; } return creaturesInDwellings; @@ -308,7 +309,7 @@ ui64 ArmyManager::howManyReinforcementsCanGet(const IBonusBearer * armyCarrier, uint64_t ArmyManager::evaluateStackPower(const CCreature * creature, int count) const { - return creature->AIValue * count; + return creature->getAIValue() * count; } SlotInfo ArmyManager::getTotalCreaturesAvailable(CreatureID creatureID) const @@ -378,12 +379,12 @@ std::vector ArmyManager::getHillFortUpgrades(const CCreatureSe CreatureID strongestUpgrade = *vstd::minElementByFun(possibleUpgrades, [](CreatureID cre) -> uint64_t { - return cre.toCreature()->AIValue; + return cre.toCreature()->getAIValue(); }); StackUpgradeInfo upgrade = StackUpgradeInfo(initial, strongestUpgrade, creature.second->count); - if(initial.toCreature()->level == 1) + if(initial.toCreature()->getLevel() == 1) upgrade.cost = TResources(); upgrades.push_back(upgrade); @@ -417,7 +418,7 @@ std::vector ArmyManager::getDwellingUpgrades(const CCreatureSe CreatureID strongestUpgrade = *vstd::minElementByFun(possibleUpgrades, [](CreatureID cre) -> uint64_t { - return cre.toCreature()->AIValue; + return cre.toCreature()->getAIValue(); }); StackUpgradeInfo upgrade = StackUpgradeInfo(initial, strongestUpgrade, creature.second->count); @@ -488,7 +489,7 @@ ArmyUpgradeInfo ArmyManager::calculateCreaturesUpgrade( upgradedArmy.power = evaluateStackPower(upgradedArmy.creature, upgradedArmy.count); auto slotToReplace = std::find_if(result.resultingArmy.begin(), result.resultingArmy.end(), [&](const SlotInfo & slot) -> bool { - return slot.count == upgradedArmy.count && slot.creature->idNumber == upgrade.initialCreature; + return slot.count == upgradedArmy.count && slot.creature->getId() == upgrade.initialCreature; }); resourcesLeft -= upgrade.cost; diff --git a/AI/Nullkiller/Analyzers/BuildAnalyzer.cpp b/AI/Nullkiller/Analyzers/BuildAnalyzer.cpp index 4ae59be8f..2988277a4 100644 --- a/AI/Nullkiller/Analyzers/BuildAnalyzer.cpp +++ b/AI/Nullkiller/Analyzers/BuildAnalyzer.cpp @@ -93,9 +93,9 @@ void BuildAnalyzer::updateOtherBuildings(TownDevelopmentInfo & developmentInfo) int32_t convertToGold(const TResources & res) { - return res[Res::GOLD] - + 75 * (res[Res::WOOD] + res[Res::ORE]) - + 125 * (res[Res::GEMS] + res[Res::CRYSTAL] + res[Res::MERCURY] + res[Res::SULFUR]); + return res[EGameResID::GOLD] + + 75 * (res[EGameResID::WOOD] + res[EGameResID::ORE]) + + 125 * (res[EGameResID::GEMS] + res[EGameResID::CRYSTAL] + res[EGameResID::MERCURY] + res[EGameResID::SULFUR]); } TResources BuildAnalyzer::getResourcesRequiredNow() const @@ -164,8 +164,8 @@ void BuildAnalyzer::update() } else { - goldPreasure = ai->getLockedResources()[Res::GOLD] / 10000.0f - + (float)armyCost[Res::GOLD] / (1 + ai->getFreeGold() + (float)dailyIncome[Res::GOLD] * 7.0f); + goldPreasure = ai->getLockedResources()[EGameResID::GOLD] / 10000.0f + + (float)armyCost[EGameResID::GOLD] / (1 + ai->getFreeGold() + (float)dailyIncome[EGameResID::GOLD] * 7.0f); } logAi->trace("Gold preasure: %f", goldPreasure); @@ -280,7 +280,7 @@ void BuildAnalyzer::updateDailyIncome() if(mine) { - dailyIncome[mine->producedResource] += mine->producedQuantity; + dailyIncome[mine->producedResource.getNum()] += mine->producedQuantity; } } @@ -355,10 +355,10 @@ BuildingInfo::BuildingInfo( if(creature) { - creatureGrows = creature->growth; - creatureID = creature->idNumber; - creatureCost = creature->cost; - creatureLevel = creature->level; + creatureGrows = creature->getGrowth(); + creatureID = creature->getId(); + creatureCost = creature->getFullRecruitCost(); + creatureLevel = creature->getLevel(); baseCreatureID = baseCreature; if(exists) @@ -367,7 +367,7 @@ BuildingInfo::BuildingInfo( } else { - creatureGrows = creature->growth; + creatureGrows = creature->getGrowth(); if(town->hasBuilt(BuildingID::CASTLE)) creatureGrows *= 2; diff --git a/AI/Nullkiller/Behaviors/BuildingBehavior.cpp b/AI/Nullkiller/Behaviors/BuildingBehavior.cpp index e41840662..29868a9ac 100644 --- a/AI/Nullkiller/Behaviors/BuildingBehavior.cpp +++ b/AI/Nullkiller/Behaviors/BuildingBehavior.cpp @@ -58,7 +58,7 @@ Goals::TGoalVec BuildingBehavior::decompose() const { for(auto & buildingInfo : developmentInfo.toBuild) { - if(goldPreasure < MAX_GOLD_PEASURE || buildingInfo.dailyIncome[Res::GOLD] > 0) + if(goldPreasure < MAX_GOLD_PEASURE || buildingInfo.dailyIncome[EGameResID::GOLD] > 0) { if(buildingInfo.notEnoughRes) { diff --git a/AI/Nullkiller/Behaviors/DefenceBehavior.cpp b/AI/Nullkiller/Behaviors/DefenceBehavior.cpp index 78c8fe261..3db20a1aa 100644 --- a/AI/Nullkiller/Behaviors/DefenceBehavior.cpp +++ b/AI/Nullkiller/Behaviors/DefenceBehavior.cpp @@ -162,7 +162,7 @@ void DefenceBehavior::evaluateDefence(Goals::TGoalVec & tasks, const CGTownInsta if(!town->visitingHero && town->hasBuilt(BuildingID::TAVERN) - && cb->getResourceAmount(Res::GOLD) > GameConstants::HERO_GOLD_COST) + && cb->getResourceAmount(EGameResID::GOLD) > GameConstants::HERO_GOLD_COST) { auto heroesInTavern = cb->getAvailableHeroes(town); diff --git a/AI/Nullkiller/Behaviors/RecruitHeroBehavior.cpp b/AI/Nullkiller/Behaviors/RecruitHeroBehavior.cpp index 82a146549..ab37ce028 100644 --- a/AI/Nullkiller/Behaviors/RecruitHeroBehavior.cpp +++ b/AI/Nullkiller/Behaviors/RecruitHeroBehavior.cpp @@ -69,7 +69,7 @@ Goals::TGoalVec RecruitHeroBehavior::decompose() const } if(cb->getHeroesInfo().size() < cb->getTownsInfo().size() + 1 - || (ai->nullkiller->getFreeResources()[Res::GOLD] > 10000 + || (ai->nullkiller->getFreeResources()[EGameResID::GOLD] > 10000 && ai->nullkiller->buildAnalyzer->getGoldPreasure() < MAX_GOLD_PEASURE)) { tasks.push_back(Goals::sptr(Goals::RecruitHero(town).setpriority(3))); diff --git a/AI/Nullkiller/Behaviors/StartupBehavior.cpp b/AI/Nullkiller/Behaviors/StartupBehavior.cpp index c05c31726..91ef62344 100644 --- a/AI/Nullkiller/Behaviors/StartupBehavior.cpp +++ b/AI/Nullkiller/Behaviors/StartupBehavior.cpp @@ -76,7 +76,7 @@ bool needToRecruitHero(const CGTownInstance * startupTown) for(auto obj : ai->nullkiller->objectClusterizer->getNearbyObjects()) { - if((obj->ID == Obj::RESOURCE && obj->subID == Res::GOLD) + if((obj->ID == Obj::RESOURCE && obj->subID == GameResID(EGameResID::GOLD)) || obj->ID == Obj::TREASURE_CHEST || obj->ID == Obj::CAMPFIRE || obj->ID == Obj::WATER_WHEEL) diff --git a/AI/Nullkiller/Engine/FuzzyEngines.cpp b/AI/Nullkiller/Engine/FuzzyEngines.cpp index ad63c0196..1ba83aa9c 100644 --- a/AI/Nullkiller/Engine/FuzzyEngines.cpp +++ b/AI/Nullkiller/Engine/FuzzyEngines.cpp @@ -65,13 +65,13 @@ armyStructure evaluateArmyStructure(const CArmedInstance * army) for(auto s : army->Slots()) { bool walker = true; - const CCreature * creature = s.second->type; - if(creature->hasBonus(selectorSHOOTER, keySHOOTER)) + auto bearer = s.second->getType()->getBonusBearer(); + if(bearer->hasBonus(selectorSHOOTER, keySHOOTER)) { shootersStrength += s.second->getPower(); walker = false; } - if(creature->hasBonus(selectorFLYING, keyFLYING)) + if(bearer->hasBonus(selectorFLYING, keyFLYING)) { flyersStrength += s.second->getPower(); walker = false; @@ -79,7 +79,7 @@ armyStructure evaluateArmyStructure(const CArmedInstance * army) if(walker) walkersStrength += s.second->getPower(); - vstd::amax(maxSpeed, creature->valOfBonuses(selectorSTACKS_SPEED, keySTACKS_SPEED)); + vstd::amax(maxSpeed, bearer->valOfBonuses(selectorSTACKS_SPEED, keySTACKS_SPEED)); } armyStructure as; as.walkers = static_cast(walkersStrength / totalStrength); diff --git a/AI/Nullkiller/Engine/Nullkiller.h b/AI/Nullkiller/Engine/Nullkiller.h index fb3bb5cc1..3a5b7bdc1 100644 --- a/AI/Nullkiller/Engine/Nullkiller.h +++ b/AI/Nullkiller/Engine/Nullkiller.h @@ -85,7 +85,7 @@ public: void unlockHero(const CGHeroInstance * hero) { lockedHeroes.erase(hero); } bool arePathHeroesLocked(const AIPath & path) const; TResources getFreeResources() const; - int32_t getFreeGold() const { return getFreeResources()[Res::GOLD]; } + int32_t getFreeGold() const { return getFreeResources()[EGameResID::GOLD]; } void lockResources(const TResources & res); const TResources & getLockedResources() const { return lockedResources; } diff --git a/AI/Nullkiller/Engine/PriorityEvaluator.cpp b/AI/Nullkiller/Engine/PriorityEvaluator.cpp index ac079ae77..1b2661d43 100644 --- a/AI/Nullkiller/Engine/PriorityEvaluator.cpp +++ b/AI/Nullkiller/Engine/PriorityEvaluator.cpp @@ -148,14 +148,15 @@ uint64_t getCreatureBankArmyReward(const CGObjectInstance * target, const CGHero for (auto c : creatures) { //Only if hero has slot for this creature in the army - if (hero->getSlotFor(c.data.type).validSlot()) + auto ccre = dynamic_cast(c.data.type); + if (hero->getSlotFor(ccre).validSlot()) { - result += (c.data.type->AIValue * c.data.count) * c.chance; + result += (c.data.type->getAIValue() * c.data.count) * c.chance; } else { //we will need to discard the weakest stack - result += (c.data.type->AIValue * c.data.count - weakestStackPower) * c.chance; + result += (c.data.type->getAIValue() * c.data.count - weakestStackPower) * c.chance; } } result /= 100; //divide by total chance @@ -173,11 +174,11 @@ uint64_t getDwellingScore(CCallback * cb, const CGObjectInstance * target, bool if(creLevel.first && creLevel.second.size()) { auto creature = creLevel.second.back().toCreature(); - auto creaturesAreFree = creature->level == 1; - if(!creaturesAreFree && checkGold && !cb->getResourceAmount().canAfford(creature->cost * creLevel.first)) + auto creaturesAreFree = creature->getLevel() == 1; + if(!creaturesAreFree && checkGold && !cb->getResourceAmount().canAfford(creature->getFullRecruitCost() * creLevel.first)) continue; - score += creature->AIValue * creLevel.first; + score += creature->getAIValue() * creLevel.first; } } @@ -194,9 +195,9 @@ int getDwellingArmyCost(const CGObjectInstance * target) if(creLevel.first && creLevel.second.size()) { auto creature = creLevel.second.back().toCreature(); - auto creaturesAreFree = creature->level == 1; + auto creaturesAreFree = creature->getLevel() == 1; if(!creaturesAreFree) - cost += creature->cost[Res::GOLD] * creLevel.first; + cost += creature->getRecruitCost(EGameResID::GOLD) * creLevel.first; } } @@ -300,7 +301,7 @@ int RewardEvaluator::getGoldCost(const CGObjectInstance * target, const CGHeroIn switch(target->ID) { case Obj::HILL_FORT: - return ai->armyManager->calculateCreaturesUpgrade(army, target, ai->cb->getResourceAmount()).upgradeCost[Res::GOLD]; + return ai->armyManager->calculateCreaturesUpgrade(army, target, ai->cb->getResourceAmount()).upgradeCost[EGameResID::GOLD]; case Obj::SCHOOL_OF_MAGIC: case Obj::SCHOOL_OF_WAR: return 1000; @@ -375,12 +376,12 @@ float RewardEvaluator::getStrategicalValue(const CGObjectInstance * target) cons switch(target->ID) { case Obj::MINE: - return target->subID == Res::GOLD + return target->subID == GameResID(EGameResID::GOLD) ? 0.5f : 0.4f * getTotalResourceRequirementStrength(target->subID) + 0.1f * getResourceRequirementStrength(target->subID); case Obj::RESOURCE: - return target->subID == Res::GOLD + return target->subID == GameResID(EGameResID::GOLD) ? 0 : 0.2f * getTotalResourceRequirementStrength(target->subID) + 0.4f * getResourceRequirementStrength(target->subID); @@ -391,7 +392,7 @@ float RewardEvaluator::getStrategicalValue(const CGObjectInstance * target) cons for (TResources::nziterator it (resourceReward); it.valid(); it++) { //Evaluate resources used for construction. Gold is evaluated separately. - if (it->resType != Res::GOLD) + if (it->resType != EGameResID::GOLD) { sum += 0.1f * getResourceRequirementStrength(it->resType); } @@ -502,7 +503,7 @@ int32_t getArmyCost(const CArmedInstance * army) for(auto stack : army->Slots()) { - value += stack.second->getCreatureID().toCreature()->cost[Res::GOLD] * stack.second->count; + value += stack.second->getCreatureID().toCreature()->getRecruitCost(EGameResID::GOLD) * stack.second->count; } return value; @@ -517,7 +518,7 @@ int32_t RewardEvaluator::getGoldReward(const CGObjectInstance * target, const CG const int dailyIncomeMultiplier = 5; const float enemyArmyEliminationGoldRewardRatio = 0.2f; const int32_t heroEliminationBonus = GameConstants::HERO_GOLD_COST / 2; - auto isGold = target->subID == Res::GOLD; // TODO: other resorces could be sold but need to evaluate market power + auto isGold = target->subID == GameResID(EGameResID::GOLD); // TODO: other resorces could be sold but need to evaluate market power switch(target->ID) { @@ -540,7 +541,7 @@ int32_t RewardEvaluator::getGoldReward(const CGObjectInstance * target, const CG case Obj::WAGON: return 100; case Obj::CREATURE_BANK: - return getCreatureBankResources(target, hero)[Res::GOLD]; + return getCreatureBankResources(target, hero)[EGameResID::GOLD]; case Obj::CRYPT: case Obj::DERELICT_SHIP: return 3000; @@ -627,7 +628,7 @@ private: continue; auto creature = creatureInfo.second.back().toCreature(); - result += creature->AIValue * town->getGrowthInfo(creature->getLevel() - 1).totalGrowth(); + result += creature->getAIValue() * town->getGrowthInfo(creature->getLevel() - 1).totalGrowth(); } return result; @@ -644,7 +645,7 @@ public: auto & treat = defendTown.getTreat(); auto armyIncome = townArmyIncome(town); - auto dailyIncome = town->dailyIncome()[Res::GOLD]; + auto dailyIncome = town->dailyIncome()[EGameResID::GOLD]; auto strategicalValue = std::sqrt(armyIncome / 20000.0f) + dailyIncome / 3000.0f; @@ -804,10 +805,10 @@ public: Goals::BuildThis & buildThis = dynamic_cast(*task); auto & bi = buildThis.buildingInfo; - evaluationContext.goldReward += 7 * bi.dailyIncome[Res::GOLD] / 2; // 7 day income but half we already have + evaluationContext.goldReward += 7 * bi.dailyIncome[EGameResID::GOLD] / 2; // 7 day income but half we already have evaluationContext.heroRole = HeroRole::MAIN; evaluationContext.movementCostByRole[evaluationContext.heroRole] += bi.prerequisitesCount; - evaluationContext.goldCost += bi.buildCostWithPrerequisits[Res::GOLD]; + evaluationContext.goldCost += bi.buildCostWithPrerequisits[EGameResID::GOLD]; if(bi.creatureID != CreatureID::NONE) { @@ -921,7 +922,7 @@ float PriorityEvaluator::evaluate(Goals::TSubgoal task) closestHeroRatioVariable->setValue(evaluationContext.closestWayRatio); strategicalValueVariable->setValue(evaluationContext.strategicalValue); goldPreasureVariable->setValue(ai->buildAnalyzer->getGoldPreasure()); - goldCostVariable->setValue(evaluationContext.goldCost / ((float)ai->getFreeResources()[Res::GOLD] + (float)ai->buildAnalyzer->getDailyIncome()[Res::GOLD] + 1.0f)); + goldCostVariable->setValue(evaluationContext.goldCost / ((float)ai->getFreeResources()[EGameResID::GOLD] + (float)ai->buildAnalyzer->getDailyIncome()[EGameResID::GOLD] + 1.0f)); turnVariable->setValue(evaluationContext.turn); fearVariable->setValue(evaluationContext.enemyHeroDangerRatio); diff --git a/AI/Nullkiller/Goals/BuyArmy.cpp b/AI/Nullkiller/Goals/BuyArmy.cpp index 8d74a7045..ddbabe936 100644 --- a/AI/Nullkiller/Goals/BuyArmy.cpp +++ b/AI/Nullkiller/Goals/BuyArmy.cpp @@ -57,12 +57,12 @@ void BuyArmy::accept(AIGateway * ai) if(objid != -1 && ci.creID != objid) continue; - vstd::amin(ci.count, res / ci.cre->cost); + vstd::amin(ci.count, res / ci.cre->getFullRecruitCost()); if(ci.count) { cb->recruitCreatures(town, town->getUpperArmy(), ci.creID, ci.count, ci.level); - valueBought += ci.count * ci.cre->AIValue; + valueBought += ci.count * ci.cre->getAIValue(); } } diff --git a/AI/Nullkiller/Goals/CompleteQuest.cpp b/AI/Nullkiller/Goals/CompleteQuest.cpp index 25dd9eb7f..9a83c69a7 100644 --- a/AI/Nullkiller/Goals/CompleteQuest.cpp +++ b/AI/Nullkiller/Goals/CompleteQuest.cpp @@ -214,7 +214,7 @@ TGoalVec CompleteQuest::missionResources() const for(int i = 0; i < q.quest->m7resources.size(); ++i) { if(q.quest->m7resources[i]) - solutions.push_back(sptr(CollectRes(i, q.quest->m7resources[i]))); + solutions.push_back(sptr(CollectRes(static_cast(i), q.quest->m7resources[i]))); } } } diff --git a/AI/Nullkiller/Goals/GatherArmy.cpp b/AI/Nullkiller/Goals/GatherArmy.cpp index ce668e7cb..b4ac7ae77 100644 --- a/AI/Nullkiller/Goals/GatherArmy.cpp +++ b/AI/Nullkiller/Goals/GatherArmy.cpp @@ -162,7 +162,7 @@ TGoalVec GatherArmy::getAllPossibleSubgoals() for(auto & creatureID : creLevel.second) { auto creature = VLC->creh->creatures[creatureID]; - if(ai->ah->freeResources().canAfford(creature->cost)) + if(ai->ah->freeResources().canAfford(creature->getFullRecruitCost())) objs.push_back(obj); //TODO: reserve resources? } } diff --git a/AI/Nullkiller/Goals/Trade.h b/AI/Nullkiller/Goals/Trade.h index 30c459be3..4360c6700 100644 --- a/AI/Nullkiller/Goals/Trade.h +++ b/AI/Nullkiller/Goals/Trade.h @@ -27,10 +27,10 @@ namespace Goals : CGoal(Goals::TRADE) { } - Trade(int rid, int val, int Objid) + Trade(GameResID rid, int val, int Objid) : CGoal(Goals::TRADE) { - resID = rid; + resID = rid.getNum(); value = val; objid = Objid; } diff --git a/AI/Nullkiller/Markers/ArmyUpgrade.cpp b/AI/Nullkiller/Markers/ArmyUpgrade.cpp index 7b8165544..bc475583d 100644 --- a/AI/Nullkiller/Markers/ArmyUpgrade.cpp +++ b/AI/Nullkiller/Markers/ArmyUpgrade.cpp @@ -23,7 +23,7 @@ using namespace Goals; ArmyUpgrade::ArmyUpgrade(const AIPath & upgradePath, const CGObjectInstance * upgrader, const ArmyUpgradeInfo & upgrade) : CGoal(Goals::ARMY_UPGRADE), upgrader(upgrader), upgradeValue(upgrade.upgradeValue), - initialValue(upgradePath.heroArmy->getArmyStrength()), goldCost(upgrade.upgradeCost[Res::GOLD]) + initialValue(upgradePath.heroArmy->getArmyStrength()), goldCost(upgrade.upgradeCost[EGameResID::GOLD]) { sethero(upgradePath.targetHero); } diff --git a/AI/Nullkiller/Pathfinding/Actors.cpp b/AI/Nullkiller/Pathfinding/Actors.cpp index 81596c0bd..59309f450 100644 --- a/AI/Nullkiller/Pathfinding/Actors.cpp +++ b/AI/Nullkiller/Pathfinding/Actors.cpp @@ -350,7 +350,7 @@ HeroExchangeArmy * HeroExchangeMap::tryUpgrade( { auto targetSlot = target->getFreeSlot(); - target->addToSlot(targetSlot, slotInfo.creature->idNumber, TQuantity(slotInfo.count)); + target->addToSlot(targetSlot, slotInfo.creature->getId(), TQuantity(slotInfo.count)); } resources -= upgradeInfo.upgradeCost; @@ -372,10 +372,10 @@ HeroExchangeArmy * HeroExchangeMap::tryUpgrade( for(auto & creatureToBuy : buyArmy) { - auto targetSlot = target->getSlotFor(creatureToBuy.cre); + auto targetSlot = target->getSlotFor(dynamic_cast(creatureToBuy.cre)); target->addToSlot(targetSlot, creatureToBuy.creID, creatureToBuy.count); - target->armyCost += creatureToBuy.cre->cost * creatureToBuy.count; + target->armyCost += creatureToBuy.cre->getFullRecruitCost() * creatureToBuy.count; target->requireBuyArmy = true; } } @@ -399,7 +399,7 @@ HeroExchangeArmy * HeroExchangeMap::pickBestCreatures(const CCreatureSet * army1 { auto targetSlot = target->getFreeSlot(); - target->addToSlot(targetSlot, slotInfo.creature->idNumber, TQuantity(slotInfo.count)); + target->addToSlot(targetSlot, slotInfo.creature->getId(), TQuantity(slotInfo.count)); } return target; @@ -420,7 +420,7 @@ DwellingActor::DwellingActor(const CGDwelling * dwelling, uint64_t chainMask, bo { for(auto & slot : creatureSet->Slots()) { - armyCost += slot.second->getCreatureID().toCreature()->cost * slot.second->count; + armyCost += slot.second->getCreatureID().toCreature()->getFullRecruitCost() * slot.second->count; } } @@ -454,7 +454,7 @@ CCreatureSet * DwellingActor::getDwellingCreatures(const CGDwelling * dwelling, auto creature = creatureInfo.second.back().toCreature(); dwellingCreatures->addToSlot( dwellingCreatures->getSlotFor(creature), - creature->idNumber, + creature->getId(), TQuantity(creatureInfo.first)); } diff --git a/AI/StupidAI/StupidAI.cpp b/AI/StupidAI/StupidAI.cpp index 23a651fa3..2a8479f9e 100644 --- a/AI/StupidAI/StupidAI.cpp +++ b/AI/StupidAI/StupidAI.cpp @@ -95,7 +95,7 @@ BattleAction CStupidAI::activeStack( const CStack * stack ) ReachabilityInfo dists = cb->getReachability(stack); std::vector enemiesShootable, enemiesReachable, enemiesUnreachable; - if(stack->type->idNumber == CreatureID::CATAPULT) + if(stack->type->getId() == CreatureID::CATAPULT) { BattleAction attack; static const std::vector wallHexes = {50, 183, 182, 130, 78, 29, 12, 95}; diff --git a/AI/VCAI/AIUtility.cpp b/AI/VCAI/AIUtility.cpp index 69cfd3b7e..c90b878c0 100644 --- a/AI/VCAI/AIUtility.cpp +++ b/AI/VCAI/AIUtility.cpp @@ -230,8 +230,8 @@ creInfo infoFromDC(const dwellingContent & dc) ci.creID = dc.second.size() ? dc.second.back() : CreatureID(-1); //should never be accessed if (ci.creID != -1) { - ci.cre = VLC->creh->objects[ci.creID]; - ci.level = ci.cre->level; //this is cretaure tier, while tryRealize expects dwelling level. Ignore. + ci.cre = VLC->creatures()->getById(ci.creID); + ci.level = ci.cre->getLevel(); //this is creature tier, while tryRealize expects dwelling level. Ignore. } else { diff --git a/AI/VCAI/AIUtility.h b/AI/VCAI/AIUtility.h index 9b78499e8..475346f21 100644 --- a/AI/VCAI/AIUtility.h +++ b/AI/VCAI/AIUtility.h @@ -152,7 +152,7 @@ struct creInfo { int count; CreatureID creID; - CCreature * cre; + const Creature * cre; int level; }; creInfo infoFromDC(const dwellingContent & dc); diff --git a/AI/VCAI/ArmyManager.cpp b/AI/VCAI/ArmyManager.cpp index 6a836e1fb..57219a5b5 100644 --- a/AI/VCAI/ArmyManager.cpp +++ b/AI/VCAI/ArmyManager.cpp @@ -36,9 +36,10 @@ std::vector ArmyManager::getSortedSlots(const CCreatureSet * target, c { for(auto & i : armyPtr->Slots()) { - auto & slotInfp = creToPower[i.second->type]; + auto cre = dynamic_cast(i.second->type); + auto & slotInfp = creToPower[cre]; - slotInfp.creature = i.second->type; + slotInfp.creature = cre; slotInfp.power += i.second->getPower(); slotInfp.count += i.second->count; } @@ -59,8 +60,8 @@ std::vector::iterator ArmyManager::getWeakestCreature(std::vector bool { - if(left.creature->level != right.creature->level) - return left.creature->level < right.creature->level; + if(left.creature->getLevel() != right.creature->getLevel()) + return left.creature->getLevel() < right.creature->getLevel(); return left.creature->Speed() > right.creature->Speed(); }); @@ -120,7 +121,7 @@ ui64 ArmyManager::howManyReinforcementsCanBuy(const CCreatureSet * h, const CGDw if(!ci.count || ci.creID == -1) continue; - vstd::amin(ci.count, availableRes / ci.cre->cost); //max count we can afford + vstd::amin(ci.count, availableRes / ci.cre->getFullRecruitCost()); //max count we can afford if(ci.count && ci.creID != -1) //valid creature at this level { @@ -135,8 +136,8 @@ ui64 ArmyManager::howManyReinforcementsCanBuy(const CCreatureSet * h, const CGDw } //we found matching occupied or free slot - aivalue += ci.count * ci.cre->AIValue; - availableRes -= ci.cre->cost * ci.count; + aivalue += ci.count * ci.cre->getAIValue(); + availableRes -= ci.cre->getFullRecruitCost() * ci.count; } } diff --git a/AI/VCAI/FuzzyEngines.cpp b/AI/VCAI/FuzzyEngines.cpp index 97449c466..a0251e3db 100644 --- a/AI/VCAI/FuzzyEngines.cpp +++ b/AI/VCAI/FuzzyEngines.cpp @@ -64,13 +64,13 @@ armyStructure evaluateArmyStructure(const CArmedInstance * army) for(auto s : army->Slots()) { bool walker = true; - const CCreature * creature = s.second->type; - if(creature->hasBonus(selectorSHOOTER, keySHOOTER)) + auto bearer = s.second->getType()->getBonusBearer(); + if(bearer->hasBonus(selectorSHOOTER, keySHOOTER)) { shootersStrength += s.second->getPower(); walker = false; } - if(creature->hasBonus(selectorFLYING, keyFLYING)) + if(bearer->hasBonus(selectorFLYING, keyFLYING)) { flyersStrength += s.second->getPower(); walker = false; @@ -78,7 +78,7 @@ armyStructure evaluateArmyStructure(const CArmedInstance * army) if(walker) walkersStrength += s.second->getPower(); - vstd::amax(maxSpeed, creature->valOfBonuses(selectorSTACKS_SPEED, keySTACKS_SPEED)); + vstd::amax(maxSpeed, bearer->valOfBonuses(selectorSTACKS_SPEED, keySTACKS_SPEED)); } armyStructure as; as.walkers = static_cast(walkersStrength / totalStrength); diff --git a/AI/VCAI/Goals/BuyArmy.cpp b/AI/VCAI/Goals/BuyArmy.cpp index fb9b4afea..f442c3dc5 100644 --- a/AI/VCAI/Goals/BuyArmy.cpp +++ b/AI/VCAI/Goals/BuyArmy.cpp @@ -35,7 +35,7 @@ TSubgoal BuyArmy::whatToDoToAchieve() { //TODO: calculate the actual cost of units instead TResources price; - price[Res::GOLD] = static_cast(value * 0.4f); //some approximate value + price[EGameResID::GOLD] = static_cast(value * 0.4f); //some approximate value return ai->ah->whatToDo(price, iAmElementar()); //buy right now or gather resources } diff --git a/AI/VCAI/Goals/CollectRes.cpp b/AI/VCAI/Goals/CollectRes.cpp index 0d0b8f822..4599bed34 100644 --- a/AI/VCAI/Goals/CollectRes.cpp +++ b/AI/VCAI/Goals/CollectRes.cpp @@ -46,7 +46,7 @@ TGoalVec CollectRes::getAllPossibleSubgoals() switch (obj->ID.num) { case Obj::TREASURE_CHEST: - return resID == Res::GOLD; + return resID == GameResID(EGameResID::GOLD); break; case Obj::RESOURCE: return obj->subID == resID; @@ -59,24 +59,24 @@ TGoalVec CollectRes::getAllPossibleSubgoals() return true; //contains all resources break; case Obj::WINDMILL: - switch (resID) + switch (GameResID(resID).toEnum()) { - case Res::GOLD: - case Res::WOOD: + case EGameResID::GOLD: + case EGameResID::WOOD: return false; } break; case Obj::WATER_WHEEL: - if (resID != Res::GOLD) + if (resID != GameResID(EGameResID::GOLD)) return false; break; case Obj::MYSTICAL_GARDEN: - if ((resID != Res::GOLD) && (resID != Res::GEMS)) + if ((resID != GameResID(EGameResID::GOLD)) && (resID != GameResID(EGameResID::GEMS))) return false; break; case Obj::LEAN_TO: case Obj::WAGON: - if (resID != Res::GOLD) + if (resID != GameResID(EGameResID::GOLD)) return false; break; default: @@ -170,12 +170,12 @@ TSubgoal CollectRes::whatToDoToTrade() const IMarket * m = markets.back(); //attempt trade at back (best prices) int howManyCanWeBuy = 0; - for (Res::ERes i = Res::WOOD; i <= Res::GOLD; vstd::advance(i, 1)) + for (auto i = EGameResID::WOOD; i <= EGameResID::GOLD; vstd::advance(i, 1)) { - if (i == resID) + if (GameResID(i) == resID) continue; int toGive = -1, toReceive = -1; - m->getOffer(i, resID, toGive, toReceive, EMarketMode::RESOURCE_RESOURCE); + m->getOffer(GameResID(i), resID, toGive, toReceive, EMarketMode::RESOURCE_RESOURCE); assert(toGive > 0 && toReceive > 0); howManyCanWeBuy += toReceive * (ai->ah->freeResources()[i] / toGive); } @@ -191,7 +191,7 @@ TSubgoal CollectRes::whatToDoToTrade() } else //either it's our town, or we have hero there { - return sptr(Trade(resID, value, objid).setisElementar(true)); //we can do this immediately + return sptr(Trade(static_cast(resID), value, objid).setisElementar(true)); //we can do this immediately } } } diff --git a/AI/VCAI/Goals/CollectRes.h b/AI/VCAI/Goals/CollectRes.h index ea2d7893c..70d76d8cc 100644 --- a/AI/VCAI/Goals/CollectRes.h +++ b/AI/VCAI/Goals/CollectRes.h @@ -24,10 +24,10 @@ namespace Goals : CGoal(Goals::COLLECT_RES) { } - CollectRes(int rid, int val) + CollectRes(GameResID rid, int val) : CGoal(Goals::COLLECT_RES) { - resID = rid; + resID = rid.getNum(); value = val; priority = 2; } diff --git a/AI/VCAI/Goals/CompleteQuest.cpp b/AI/VCAI/Goals/CompleteQuest.cpp index 9fc6a326f..571ed9e1c 100644 --- a/AI/VCAI/Goals/CompleteQuest.cpp +++ b/AI/VCAI/Goals/CompleteQuest.cpp @@ -172,7 +172,7 @@ TGoalVec CompleteQuest::missionArmy() const for(auto creature : q.quest->m6creatures) { - solutions.push_back(sptr(GatherTroops(creature.type->idNumber, creature.count))); + solutions.push_back(sptr(GatherTroops(creature.type->getId(), creature.count))); } return solutions; @@ -235,7 +235,7 @@ TGoalVec CompleteQuest::missionResources() const for(int i = 0; i < q.quest->m7resources.size(); ++i) { if(q.quest->m7resources[i]) - solutions.push_back(sptr(CollectRes(i, q.quest->m7resources[i]))); + solutions.push_back(sptr(CollectRes(static_cast(i), q.quest->m7resources[i]))); } } } diff --git a/AI/VCAI/Goals/GatherArmy.cpp b/AI/VCAI/Goals/GatherArmy.cpp index 8f092d70a..bfc6daf5d 100644 --- a/AI/VCAI/Goals/GatherArmy.cpp +++ b/AI/VCAI/Goals/GatherArmy.cpp @@ -159,7 +159,7 @@ TGoalVec GatherArmy::getAllPossibleSubgoals() for(auto & creatureID : creLevel.second) { auto creature = VLC->creh->objects[creatureID]; - if(ai->ah->freeResources().canAfford(creature->cost)) + if(ai->ah->freeResources().canAfford(creature->getFullRecruitCost())) objs.push_back(obj); //TODO: reserve resources? } } diff --git a/AI/VCAI/Goals/GatherTroops.cpp b/AI/VCAI/Goals/GatherTroops.cpp index 9c70cba67..58777be67 100644 --- a/AI/VCAI/Goals/GatherTroops.cpp +++ b/AI/VCAI/Goals/GatherTroops.cpp @@ -93,21 +93,21 @@ TGoalVec GatherTroops::getAllPossibleSubgoals() continue; } - auto creature = VLC->creh->objects[objid]; - if(t->subID == creature->faction) //TODO: how to force AI to build unupgraded creatures? :O + auto creature = VLC->creatures()->getByIndex(objid); + if(t->subID == creature->getFactionIndex()) //TODO: how to force AI to build unupgraded creatures? :O { - auto creatures = vstd::tryAt(t->town->creatures, creature->level - 1); + auto creatures = vstd::tryAt(t->town->creatures, creature->getLevel() - 1); if(!creatures) continue; - int upgradeNumber = vstd::find_pos(*creatures, creature->idNumber); + int upgradeNumber = vstd::find_pos(*creatures, creature->getId()); if(upgradeNumber < 0) continue; - BuildingID bid(BuildingID::DWELL_FIRST + creature->level - 1 + upgradeNumber * GameConstants::CREATURES_PER_TOWN); - if(t->hasBuilt(bid) && ai->ah->freeResources().canAfford(creature->cost)) //this assumes only creatures with dwellings are assigned to faction + BuildingID bid(BuildingID::DWELL_FIRST + creature->getLevel() - 1 + upgradeNumber * GameConstants::CREATURES_PER_TOWN); + 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->AIValue * this->value).setobjid(objid))); + solutions.push_back(sptr(BuyArmy(t, creature->getAIValue() * this->value).setobjid(objid))); } /*else //disable random building requests for now - this code needs to know a lot of town/resource context to do more good than harm { @@ -129,7 +129,7 @@ TGoalVec GatherTroops::getAllPossibleSubgoals() { for(auto type : creature.second) { - if(type == objid && ai->ah->freeResources().canAfford(VLC->creh->objects[type]->cost)) + if(type == objid && ai->ah->freeResources().canAfford(VLC->creatures()->getById(type)->getFullRecruitCost())) vstd::concatenate(solutions, ai->ah->howToVisitObj(obj)); } } diff --git a/AI/VCAI/Goals/RecruitHero.cpp b/AI/VCAI/Goals/RecruitHero.cpp index aff943bc6..314efb3b6 100644 --- a/AI/VCAI/Goals/RecruitHero.cpp +++ b/AI/VCAI/Goals/RecruitHero.cpp @@ -33,6 +33,6 @@ TSubgoal RecruitHero::whatToDoToAchieve() return sptr(BuildThis(BuildingID::TAVERN).setpriority(2)); TResources res; - res[Res::GOLD] = GameConstants::HERO_GOLD_COST; + res[EGameResID::GOLD] = GameConstants::HERO_GOLD_COST; return ai->ah->whatToDo(res, iAmElementar()); //either buy immediately, or collect res } diff --git a/AI/VCAI/Goals/Trade.h b/AI/VCAI/Goals/Trade.h index c8da46fc2..c8f64416f 100644 --- a/AI/VCAI/Goals/Trade.h +++ b/AI/VCAI/Goals/Trade.h @@ -24,10 +24,10 @@ namespace Goals : CGoal(Goals::TRADE) { } - Trade(int rid, int val, int Objid) + Trade(GameResID rid, int val, int Objid) : CGoal(Goals::TRADE) { - resID = rid; + resID = rid.getNum(); value = val; objid = Objid; priority = 3; //trading is instant, but picking resources is free diff --git a/AI/VCAI/Goals/Win.cpp b/AI/VCAI/Goals/Win.cpp index bf37f6ce0..5fc7a4bc3 100644 --- a/AI/VCAI/Goals/Win.cpp +++ b/AI/VCAI/Goals/Win.cpp @@ -154,7 +154,7 @@ TSubgoal Win::whatToDoToAchieve() case EventCondition::HAVE_RESOURCES: //TODO mines? piles? marketplace? //save? - return sptr(CollectRes(static_cast(goal.objectType), goal.value)); + return sptr(CollectRes(static_cast(goal.objectType), goal.value)); case EventCondition::HAVE_CREATURES: return sptr(GatherTroops(goal.objectType, goal.value)); case EventCondition::TRANSPORT: diff --git a/AI/VCAI/MapObjectsEvaluator.cpp b/AI/VCAI/MapObjectsEvaluator.cpp index 516e72b2a..83595b8b4 100644 --- a/AI/VCAI/MapObjectsEvaluator.cpp +++ b/AI/VCAI/MapObjectsEvaluator.cpp @@ -73,8 +73,8 @@ boost::optional MapObjectsEvaluator::getObjectValue(const CGObjectInstance { for(auto & creatureID : creLevel.second) { - auto creature = VLC->creh->objects[creatureID]; - aiValue += (creature->AIValue * creature->growth); + auto creature = VLC->creatures()->getById(creatureID); + aiValue += (creature->getAIValue() * creature->getGrowth()); } } return aiValue; diff --git a/AI/VCAI/ResourceManager.cpp b/AI/VCAI/ResourceManager.cpp index d676c4488..c8c3f3a33 100644 --- a/AI/VCAI/ResourceManager.cpp +++ b/AI/VCAI/ResourceManager.cpp @@ -58,15 +58,15 @@ TResources ResourceManager::estimateIncome() const { if (obj->ID == Obj::MINE) { - switch (obj->subID) + auto mine = dynamic_cast(obj); + switch (mine->producedResource.toEnum()) { - case Res::WOOD: - case Res::ORE: + case EGameResID::WOOD: + case EGameResID::ORE: ret[obj->subID] += WOOD_ORE_MINE_PRODUCTION; break; - case Res::GOLD: - case 7: //abandoned mine -> also gold - ret[Res::GOLD] += GOLD_MINE_PRODUCTION; + case EGameResID::GOLD: + ret[EGameResID::GOLD] += GOLD_MINE_PRODUCTION; break; default: ret[obj->subID] += RESOURCE_MINE_PRODUCTION; @@ -90,11 +90,11 @@ Goals::TSubgoal ResourceManager::collectResourcesForOurGoal(ResourceObjective &o { auto allResources = cb->getResourceAmount(); auto income = estimateIncome(); - Res::ERes resourceType = Res::INVALID; + GameResID resourceType = EGameResID::INVALID; TResource amountToCollect = 0; - typedef std::pair resPair; - std::map missingResources; + using resPair = std::pair; + std::map missingResources; //TODO: unit test for complex resource sets @@ -102,10 +102,10 @@ Goals::TSubgoal ResourceManager::collectResourcesForOurGoal(ResourceObjective &o for (auto it = queue.ordered_begin(); it != queue.ordered_end(); it++) { //choose specific resources we need for this goal (not 0) - for (auto r = Res::ResourceSet::nziterator(o.resources); r.valid(); r++) + for (auto r = ResourceSet::nziterator(o.resources); r.valid(); r++) missingResources[r->resType] += it->resources[r->resType]; //goal it costs r units of resType } - for (auto it = Res::ResourceSet::nziterator(o.resources); it.valid(); it++) + for (auto it = ResourceSet::nziterator(o.resources); it.valid(); it++) { missingResources[it->resType] -= allResources[it->resType]; //missing = (what we need) - (what we have) vstd::amax(missingResources[it->resType], 0); // if we have more resources than reserved, we don't need them @@ -129,11 +129,11 @@ Goals::TSubgoal ResourceManager::collectResourcesForOurGoal(ResourceObjective &o break; } } - if (resourceType == Res::INVALID) //no needed resources has 0 income, + if (resourceType == EGameResID::INVALID) //no needed resources has 0 income, { //find the one which takes longest to collect - typedef std::pair timePair; - std::map daysToEarn; + using timePair = std::pair; + std::map daysToEarn; for (auto it : missingResources) daysToEarn[it.first] = (float)missingResources[it.first] / income[it.first]; auto incomeComparer = [](const timePair & lhs, const timePair & rhs) -> bool @@ -345,7 +345,7 @@ TResources ResourceManager::freeResources() const TResource ResourceManager::freeGold() const { - return freeResources()[Res::GOLD]; + return freeResources()[EGameResID::GOLD]; } TResources ResourceManager::allResources() const @@ -355,5 +355,5 @@ TResources ResourceManager::allResources() const TResource ResourceManager::allGold() const { - return cb->getResourceAmount()[Res::GOLD]; + return cb->getResourceAmount()[EGameResID::GOLD]; } diff --git a/AI/VCAI/VCAI.cpp b/AI/VCAI/VCAI.cpp index d329c3a75..a650adf44 100644 --- a/AI/VCAI/VCAI.cpp +++ b/AI/VCAI/VCAI.cpp @@ -1235,7 +1235,7 @@ void VCAI::recruitCreatures(const CGDwelling * d, const CArmedInstance * recruit int count = d->creatures[i].first; CreatureID creID = d->creatures[i].second.back(); - vstd::amin(count, ah->freeResources() / VLC->creh->objects[creID]->cost); + vstd::amin(count, ah->freeResources() / VLC->creatures()->getById(creID)->getFullRecruitCost()); if(count > 0) cb->recruitCreatures(d, recruiter, creID, count, i); } @@ -1314,7 +1314,7 @@ bool VCAI::canRecruitAnyHero(const CGTownInstance * t) const t = findTownWithTavern(); if(!t) return false; - if(cb->getResourceAmount(Res::GOLD) < GameConstants::HERO_GOLD_COST) //TODO: use ResourceManager + if(cb->getResourceAmount(EGameResID::GOLD) < GameConstants::HERO_GOLD_COST) //TODO: use ResourceManager return false; if(cb->getHeroesInfo().size() >= ALLOWED_ROAMING_HEROES) return false; @@ -1434,7 +1434,7 @@ void VCAI::wander(HeroPtr h) } break; } - else if(cb->getResourceAmount(Res::GOLD) >= GameConstants::HERO_GOLD_COST) + else if(cb->getResourceAmount(EGameResID::GOLD) >= GameConstants::HERO_GOLD_COST) { std::vector towns = cb->getTownsInfo(); vstd::erase_if(towns, [&](const CGTownInstance * t) -> bool @@ -2117,10 +2117,10 @@ void VCAI::tryRealize(Goals::Trade & g) //trade if(const IMarket * m = IMarket::castFrom(obj, false)) { auto freeRes = ah->freeResources(); //trade only resources which are not reserved - for(auto it = Res::ResourceSet::nziterator(freeRes); it.valid(); it++) + for(auto it = ResourceSet::nziterator(freeRes); it.valid(); it++) { auto res = it->resType; - if(res == g.resID) //sell any other resource + if(res.getNum() == g.resID) //sell any other resource continue; int toGive, toGet; @@ -2174,7 +2174,7 @@ void VCAI::tryRealize(Goals::BuyArmy & g) || t->getUpperArmy()->getSlotFor(ci.creID) == SlotID()) continue; - vstd::amin(ci.count, res / ci.cre->cost); //max count we can afford + vstd::amin(ci.count, res / ci.cre->getFullRecruitCost()); //max count we can afford if(!ci.count) continue; @@ -2190,15 +2190,15 @@ void VCAI::tryRealize(Goals::BuyArmy & g) *boost::max_element(creaturesInDwellings, [](const creInfo & lhs, const creInfo & rhs) { //max value of creatures we can buy with our res - int value1 = lhs.cre->AIValue * lhs.count, - value2 = rhs.cre->AIValue * rhs.count; + int value1 = lhs.cre->getAIValue() * lhs.count, + value2 = rhs.cre->getAIValue() * rhs.count; return value1 < value2; }); cb->recruitCreatures(t, t->getUpperArmy(), ci.creID, ci.count, ci.level); - valueBought += ci.count * ci.cre->AIValue; + valueBought += ci.count * ci.cre->getAIValue(); } throw goalFulfilledException(sptr(g)); //we bought as many creatures as we wanted @@ -2820,7 +2820,7 @@ bool shouldVisit(HeroPtr h, const CGObjectInstance * obj) { for(auto slot : h->Slots()) { - if(slot.second->type->upgrades.size()) + if(slot.second->type->hasUpgrades()) return true; //TODO: check price? } return false; @@ -2844,7 +2844,7 @@ bool shouldVisit(HeroPtr h, const CGObjectInstance * obj) case Obj::TREE_OF_KNOWLEDGE: { TResources myRes = ai->ah->freeResources(); - if(myRes[Res::GOLD] < 2000 || myRes[Res::GEMS] < 10) + if(myRes[EGameResID::GOLD] < 2000 || myRes[EGameResID::GEMS] < 10) return false; break; } diff --git a/Global.h b/Global.h index c9904e6f6..a2fe92e6b 100644 --- a/Global.h +++ b/Global.h @@ -279,7 +279,7 @@ template char (&_ArrayCountObj(const T (&)[N]))[N]; #define VCMI_LIB_NAMESPACE_BEGIN #define VCMI_LIB_NAMESPACE_END #define VCMI_LIB_USING_NAMESPACE -#define VCMI_LIB_WRAP_NAMESPACE(x) x +#define VCMI_LIB_WRAP_NAMESPACE(x) ::x #endif /* ---------------------------------------------------------------------------- */ diff --git a/client/Client.h b/client/Client.h index b360d32fb..c1aee94de 100644 --- a/client/Client.h +++ b/client/Client.h @@ -195,7 +195,7 @@ public: void showGarrisonDialog(ObjectInstanceID upobj, ObjectInstanceID hid, bool removableUnits) override {}; void showTeleportDialog(TeleportDialog * iw) override {}; void showThievesGuildWindow(PlayerColor player, ObjectInstanceID requestingObjId) override {}; - void giveResource(PlayerColor player, Res::ERes which, int val) override {}; + void giveResource(PlayerColor player, GameResID which, int val) override {}; virtual void giveResources(PlayerColor player, TResources resources) override {}; void giveCreatures(const CArmedInstance * objid, const CGHeroInstance * h, const CCreatureSet & creatures, bool remove) override {}; diff --git a/client/adventureMap/CResDataBar.cpp b/client/adventureMap/CResDataBar.cpp index 8d4cf1b91..33cb30f0a 100644 --- a/client/adventureMap/CResDataBar.cpp +++ b/client/adventureMap/CResDataBar.cpp @@ -80,7 +80,7 @@ std::string CResDataBar::buildDateString() void CResDataBar::draw(SDL_Surface * to) { //TODO: all this should be labels, but they require proper text update on change - for (auto i=Res::WOOD; i<=Res::GOLD; vstd::advance(i, 1)) + for (auto i=GameResID(EGameResID::WOOD); i <= GameResID(EGameResID::GOLD); vstd::advance(i, 1)) { std::string text = std::to_string(LOCPLINT->cb->getResourceAmount(i)); diff --git a/client/battle/BattleAnimationClasses.cpp b/client/battle/BattleAnimationClasses.cpp index 6504dd8ab..6eb0308ce 100644 --- a/client/battle/BattleAnimationClasses.cpp +++ b/client/battle/BattleAnimationClasses.cpp @@ -158,7 +158,7 @@ ECreatureAnimType AttackAnimation::findValidGroup( const std::vectorgetCreature()->idNumber == CreatureID::ARROW_TOWERS) + if (attackingStack->getCreature()->getId() == CreatureID::ARROW_TOWERS) return owner.siegeController->getTurretCreature(); else return attackingStack->getCreature(); diff --git a/client/battle/BattleInterfaceClasses.cpp b/client/battle/BattleInterfaceClasses.cpp index 7614b9e82..a98beb89a 100644 --- a/client/battle/BattleInterfaceClasses.cpp +++ b/client/battle/BattleInterfaceClasses.cpp @@ -453,7 +453,7 @@ BattleResultWindow::BattleResultWindow(const BattleResult & br, CPlayerInterface auto best = vstd::maxElementByFun(stacks, [](const CStack * stack) { - return stack->type->AIValue; + return stack->type->getAIValue(); }); if(best != stacks.end()) //should be always but to be safe... @@ -715,7 +715,7 @@ void StackQueue::StackBox::setUnit(const battle::Unit * unit, size_t turn) // if mod is not up to date and does have arrow tower icon yet - second setFrame call will fail and retain previously set image // for 1.2 release & later next line should be moved into 'else' block icon->setFrame(unit->creatureIconIndex(), 0); - if (unit->unitType()->idNumber == CreatureID::ARROW_TOWERS) + if (unit->unitType()->getId() == CreatureID::ARROW_TOWERS) icon->setFrame(owner->getSiegeShooterIconID(), 1); amount->setText(TextOperations::formatMetric(unit->getCount(), 4)); diff --git a/client/battle/BattleProjectileController.cpp b/client/battle/BattleProjectileController.cpp index eb9d8b6fe..c24832eb8 100644 --- a/client/battle/BattleProjectileController.cpp +++ b/client/battle/BattleProjectileController.cpp @@ -148,7 +148,7 @@ const CCreature & BattleProjectileController::getShooter(const CStack * stack) c { const CCreature * creature = stack->getCreature(); - if(creature->idNumber == CreatureID::ARROW_TOWERS) + if(creature->getId() == CreatureID::ARROW_TOWERS) creature = owner.siegeController->getTurretCreature(); if(creature->animation.missleFrameAngles.empty()) diff --git a/client/battle/BattleStacksController.cpp b/client/battle/BattleStacksController.cpp index 6ab140814..e21518bad 100644 --- a/client/battle/BattleStacksController.cpp +++ b/client/battle/BattleStacksController.cpp @@ -200,7 +200,7 @@ void BattleStacksController::stackAdded(const CStack * stack, bool instant) stackAnimation[stack->ID]->pos.w = stackAnimation[stack->ID]->getWidth(); // FIXME: workaround for visible animation of Medusa tails (animation disabled in H3) - if (turretCreature->idNumber == CreatureID::MEDUSA ) + if (turretCreature->getId() == CreatureID::MEDUSA ) stackAnimation[stack->ID]->pos.w = 250; coords = owner.siegeController->getTurretCreaturePosition(stack->initialPosition); diff --git a/client/battle/BattleWindow.cpp b/client/battle/BattleWindow.cpp index b9d308764..381523c69 100644 --- a/client/battle/BattleWindow.cpp +++ b/client/battle/BattleWindow.cpp @@ -309,7 +309,7 @@ void BattleWindow::reallyFlee() void BattleWindow::reallySurrender() { - if (owner.curInt->cb->getResourceAmount(Res::GOLD) < owner.curInt->cb->battleGetSurrenderCost()) + if (owner.curInt->cb->getResourceAmount(EGameResID::GOLD) < owner.curInt->cb->battleGetSurrenderCost()) { owner.curInt->showInfoDialog(CGI->generaltexth->allTexts[29]); //You don't have enough gold! } diff --git a/client/lobby/OptionsTab.cpp b/client/lobby/OptionsTab.cpp index 31c8b4d28..9702bfc47 100644 --- a/client/lobby/OptionsTab.cpp +++ b/client/lobby/OptionsTab.cpp @@ -126,25 +126,25 @@ size_t OptionsTab::CPlayerSettingsHelper::getImageIndex() return GOLD; case PlayerSettings::RESOURCE: { - switch((*CGI->townh)[factionIndex]->town->primaryRes) + switch((*CGI->townh)[factionIndex]->town->primaryRes.toEnum()) { - case Res::WOOD_AND_ORE: + case EGameResID::WOOD_AND_ORE: return WOOD_ORE; - case Res::WOOD: + case EGameResID::WOOD: return WOOD; - case Res::MERCURY: + case EGameResID::MERCURY: return MERCURY; - case Res::ORE: + case EGameResID::ORE: return ORE; - case Res::SULFUR: + case EGameResID::SULFUR: return SULFUR; - case Res::CRYSTAL: + case EGameResID::CRYSTAL: return CRYSTAL; - case Res::GEMS: + case EGameResID::GEMS: return GEM; - case Res::GOLD: + case EGameResID::GOLD: return GOLD; - case Res::MITHRIL: + case EGameResID::MITHRIL: return MITHRIL; } } @@ -268,17 +268,17 @@ std::string OptionsTab::CPlayerSettingsHelper::getSubtitle() return CGI->generaltexth->allTexts[87]; //500-1000 case PlayerSettings::RESOURCE: { - switch((*CGI->townh)[factionIndex]->town->primaryRes) + switch((*CGI->townh)[factionIndex]->town->primaryRes.toEnum()) { - case Res::MERCURY: + case EGameResID::MERCURY: return CGI->generaltexth->allTexts[694]; - case Res::SULFUR: + case EGameResID::SULFUR: return CGI->generaltexth->allTexts[695]; - case Res::CRYSTAL: + case EGameResID::CRYSTAL: return CGI->generaltexth->allTexts[692]; - case Res::GEMS: + case EGameResID::GEMS: return CGI->generaltexth->allTexts[693]; - case Res::WOOD_AND_ORE: + case EGameResID::WOOD_AND_ORE: return CGI->generaltexth->allTexts[89]; //At the start of the game, 5-10 wood and 5-10 ore are added to your Kingdom's resource pool } } @@ -310,17 +310,17 @@ std::string OptionsTab::CPlayerSettingsHelper::getDescription() return CGI->generaltexth->allTexts[92]; //At the start of the game, 500-1000 gold is added to your Kingdom's resource pool case PlayerSettings::RESOURCE: { - switch((*CGI->townh)[factionIndex]->town->primaryRes) + switch((*CGI->townh)[factionIndex]->town->primaryRes.toEnum()) { - case Res::MERCURY: + case EGameResID::MERCURY: return CGI->generaltexth->allTexts[690]; - case Res::SULFUR: + case EGameResID::SULFUR: return CGI->generaltexth->allTexts[691]; - case Res::CRYSTAL: + case EGameResID::CRYSTAL: return CGI->generaltexth->allTexts[688]; - case Res::GEMS: + case EGameResID::GEMS: return CGI->generaltexth->allTexts[689]; - case Res::WOOD_AND_ORE: + case EGameResID::WOOD_AND_ORE: return CGI->generaltexth->allTexts[93]; //At the start of the game, 5-10 wood and 5-10 ore are added to your Kingdom's resource pool } } diff --git a/client/widgets/CreatureCostBox.h b/client/widgets/CreatureCostBox.h index 338101ebc..9f5ec4f8e 100644 --- a/client/widgets/CreatureCostBox.h +++ b/client/widgets/CreatureCostBox.h @@ -26,5 +26,5 @@ private: using ImagePtr = std::shared_ptr; LabelPtr title; - std::map> resources; + std::map> resources; }; diff --git a/client/widgets/MiscWidgets.cpp b/client/widgets/MiscWidgets.cpp index 8217a14f6..1e0dbaeb0 100644 --- a/client/widgets/MiscWidgets.cpp +++ b/client/widgets/MiscWidgets.cpp @@ -200,11 +200,11 @@ void CMinorResDataBar::showAll(SDL_Surface * to) { CIntObject::showAll(to); - for (Res::ERes i=Res::WOOD; i<=Res::GOLD; vstd::advance(i, 1)) + for (EGameResID i=EGameResID::WOOD; i<=EGameResID::GOLD; vstd::advance(i, 1)) { std::string text = std::to_string(LOCPLINT->cb->getResourceAmount(i)); - graphics->fonts[FONT_SMALL]->renderTextCenter(to, text, Colors::WHITE, Point(pos.x + 50 + 76 * i, pos.y + pos.h/2)); + graphics->fonts[FONT_SMALL]->renderTextCenter(to, text, Colors::WHITE, Point(pos.x + 50 + 76 * GameResID(i), pos.y + pos.h/2)); } graphics->fonts[FONT_SMALL]->renderTextCenter(to, buildDateString(), Colors::WHITE, Point(pos.x+545+(pos.w-545)/2,pos.y+pos.h/2)); } @@ -347,10 +347,10 @@ void CTownTooltip::init(const InfoAboutTown & town) if(town.details->customRes)//silo is built { - if(town.tType->primaryRes == Res::WOOD_AND_ORE )// wood & ore + if(town.tType->primaryRes == EGameResID::WOOD_AND_ORE )// wood & ore { - res1 = std::make_shared("SMALRES", Res::WOOD, 0, 7, 75); - res2 = std::make_shared("SMALRES", Res::ORE , 0, 7, 88); + res1 = std::make_shared("SMALRES", GameResID(EGameResID::WOOD), 0, 7, 75); + res2 = std::make_shared("SMALRES", GameResID(EGameResID::ORE), 0, 7, 88); } else { @@ -448,7 +448,7 @@ CCreaturePic::CCreaturePic(int x, int y, const CCreature * cre, bool Big, bool A pos.x+=x; pos.y+=y; - TFaction faction = cre->faction; + TFaction faction = cre->getFactionIndex(); assert(CGI->townh->size() > faction); diff --git a/client/windows/CCastleInterface.cpp b/client/windows/CCastleInterface.cpp index 78e36f671..f2c8bcbf1 100644 --- a/client/windows/CCastleInterface.cpp +++ b/client/windows/CCastleInterface.cpp @@ -292,10 +292,11 @@ CDwellingInfoBox::CDwellingInfoBox(int centerX, int centerY, const CGTownInstanc for(int i = 0; icost[i]) + auto res = static_cast(i); + if(creature->getRecruitCost(res)) { resPicture.push_back(std::make_shared("RESOURCE", i, 0, 0, 0)); - resAmount.push_back(std::make_shared(0,0, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE, std::to_string(creature->cost[i]))); + resAmount.push_back(std::make_shared(0,0, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE, std::to_string(creature->getRecruitCost(res)))); } } @@ -810,7 +811,7 @@ void CCastleBuildings::enterBlacksmith(ArtifactID artifactID) auto art = artifactID.toArtifact(); int price = art->getPrice(); - bool possible = LOCPLINT->cb->getResourceAmount(Res::GOLD) >= price; + bool possible = LOCPLINT->cb->getResourceAmount(EGameResID::GOLD) >= price; if(possible) { for(auto slot : art->possibleSlots.at(ArtBearer::HERO)) @@ -942,7 +943,7 @@ void CCastleBuildings::enterMagesGuild() // "Yog has given up magic in all its forms..." LOCPLINT->showInfoDialog(CGI->generaltexth->allTexts[736]); } - else if(LOCPLINT->cb->getResourceAmount(Res::GOLD) < 500) //not enough gold to buy spellbook + else if(LOCPLINT->cb->getResourceAmount(EGameResID::GOLD) < 500) //not enough gold to buy spellbook { openMagesGuild(); LOCPLINT->showInfoDialog(CGI->generaltexth->allTexts[213]); @@ -1100,7 +1101,7 @@ void CCreaInfo::clickRight(tribool down, bool previousState) if (showAvailable) GH.pushIntT(GH.screenDimensions().x / 2, GH.screenDimensions().y / 2, town, level); else - CRClickPopup::createAndPush(genGrowthText(), std::make_shared(CComponent::creature, creature->idNumber)); + CRClickPopup::createAndPush(genGrowthText(), std::make_shared(CComponent::creature, creature->getId())); } } @@ -1279,7 +1280,7 @@ void CCastleInterface::recreateIcons() icon->setFrame(iconIndex); TResources townIncome = town->dailyIncome(); - income->setText(std::to_string(townIncome[Res::GOLD])); + income->setText(std::to_string(townIncome[EGameResID::GOLD])); hall = std::make_shared(80, 413, town, true); fort = std::make_shared(122, 413, town, false); @@ -1870,5 +1871,5 @@ CBlacksmithDialog::CBlacksmithDialog(bool possible, CreatureID creMachineID, Art else buy->block(true); - costIcon = std::make_shared("RESOURCE", Res::GOLD, 0, 148, 244); + costIcon = std::make_shared("RESOURCE", GameResID(EGameResID::GOLD), 0, 148, 244); } diff --git a/client/windows/CCreatureWindow.cpp b/client/windows/CCreatureWindow.cpp index ed0fe6a9e..beda2681d 100644 --- a/client/windows/CCreatureWindow.cpp +++ b/client/windows/CCreatureWindow.cpp @@ -323,7 +323,7 @@ CStackWindow::ButtonsSection::ButtonsSection(CStackWindow * owner, int yOffset) }; auto upgradeBtn = std::make_shared(Point(221 + (int)buttonIndex * 40, 5), "stackWindow/upgradeButton", CGI->generaltexth->zelp[446], onClick, SDLK_1); - upgradeBtn->addOverlay(std::make_shared("CPRSMALL", VLC->creh->objects[upgradeInfo.info.newID[buttonIndex]]->iconIndex)); + upgradeBtn->addOverlay(std::make_shared("CPRSMALL", VLC->creh->objects[upgradeInfo.info.newID[buttonIndex]]->getIconIndex())); if(buttonsToCreate == 1) // single upgrade avaialbe { @@ -844,7 +844,7 @@ std::string CStackWindow::generateStackExpDescription() const CStackInstance * stack = info->stackNode; const CCreature * creature = info->creature; - int tier = stack->type->level; + int tier = stack->type->getLevel(); int rank = stack->getExpRank(); if (!vstd::iswithin(tier, 1, 7)) tier = 0; diff --git a/client/windows/CKingdomInterface.cpp b/client/windows/CKingdomInterface.cpp index 250ddfaf4..22365d323 100644 --- a/client/windows/CKingdomInterface.cpp +++ b/client/windows/CKingdomInterface.cpp @@ -564,7 +564,7 @@ std::shared_ptr CKingdomInterface::createMainTab(size_t index) void CKingdomInterface::generateMinesList(const std::vector & ownedObjects) { ui32 footerPos = conf.go()->ac.overviewSize * 116; - std::vector minesCount(GameConstants::RESOURCE_QUANTITY, 0); + TResources minesCount(GameConstants::RESOURCE_QUANTITY, 0); int totalIncome=0; for(const CGObjectInstance * object : ownedObjects) @@ -576,7 +576,7 @@ void CKingdomInterface::generateMinesList(const std::vectorproducedResource]++; - if (mine->producedResource == Res::GOLD) + if (mine->producedResource == EGameResID::GOLD) totalIncome += mine->producedQuantity; } } @@ -585,14 +585,14 @@ void CKingdomInterface::generateMinesList(const std::vector heroes = LOCPLINT->cb->getHeroesInfo(true); for(auto & heroe : heroes) { - totalIncome += heroe->valOfBonuses(Selector::typeSubtype(Bonus::GENERATE_RESOURCE, Res::GOLD)); + totalIncome += heroe->valOfBonuses(Selector::typeSubtype(Bonus::GENERATE_RESOURCE, GameResID(EGameResID::GOLD))); } //Add town income of all towns std::vector towns = LOCPLINT->cb->getTownsInfo(true); for(auto & town : towns) { - totalIncome += town->dailyIncome()[Res::GOLD]; + totalIncome += town->dailyIncome()[EGameResID::GOLD]; } for(int i=0; i<7; i++) { @@ -772,7 +772,7 @@ CTownItem::CTownItem(const CGTownInstance * Town) background = std::make_shared("OVSLOT", 6); name = std::make_shared(74, 8, FONT_SMALL, ETextAlignment::TOPLEFT, Colors::WHITE, town->getNameTranslated()); - income = std::make_shared( 190, 60, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE, std::to_string(town->dailyIncome()[Res::GOLD])); + income = std::make_shared( 190, 60, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE, std::to_string(town->dailyIncome()[EGameResID::GOLD])); hall = std::make_shared( 69, 31, town, true); fort = std::make_shared(111, 31, town, false); @@ -801,7 +801,7 @@ void CTownItem::updateGarrisons() void CTownItem::update() { - std::string incomeVal = std::to_string(town->dailyIncome()[Res::GOLD]); + std::string incomeVal = std::to_string(town->dailyIncome()[EGameResID::GOLD]); if (incomeVal != income->getText()) income->setText(incomeVal); diff --git a/client/windows/CTradeWindow.cpp b/client/windows/CTradeWindow.cpp index ff6846b02..0c16f51f4 100644 --- a/client/windows/CTradeWindow.cpp +++ b/client/windows/CTradeWindow.cpp @@ -191,7 +191,7 @@ void CTradeWindow::CTradeableItem::clickLeft(tribool down, bool previousState) aw->arts->markPossibleSlots(art); //aw->arts->commonInfo->dst.AOH = aw->arts; - CCS->curh->dragAndDropCursor("artifact", art->artType->iconIndex); + CCS->curh->dragAndDropCursor("artifact", art->artType->getIconIndex()); aw->arts->artifactsOnAltar.erase(art); setID(-1); @@ -447,7 +447,7 @@ std::vector *CTradeWindow::getItemsIds(bool Left) for(int i = 0; i < 7; i++) { if(const CCreature *c = hero->getCreature(SlotID(i))) - ids->push_back(c->idNumber); + ids->push_back(c->getId()); else ids->push_back(-1); } @@ -535,7 +535,7 @@ void CTradeWindow::initSubs(bool Left) item->subtitle = std::to_string(hero->getStackCount(SlotID(item->serial))); break; case RESOURCE: - item->subtitle = std::to_string(LOCPLINT->cb->getResourceAmount(static_cast(item->serial))); + item->subtitle = std::to_string(LOCPLINT->cb->getResourceAmount(static_cast(item->serial))); break; } } @@ -869,7 +869,7 @@ void CMarketplaceWindow::selectionChanged(bool side) { int newAmount = -1; if(itemsType[1] == RESOURCE) - newAmount = LOCPLINT->cb->getResourceAmount(static_cast(soldItemId)); + newAmount = LOCPLINT->cb->getResourceAmount(static_cast(soldItemId)); else if(itemsType[1] == CREATURE) newAmount = hero->getStackCount(SlotID(hLeft->serial)) - (hero->stacksCount() == 1 && hero->needsLastStack()); else @@ -882,7 +882,7 @@ void CMarketplaceWindow::selectionChanged(bool side) } else if(itemsType[1] == RESOURCE) //buying -> check if we can afford transaction { - deal->block(LOCPLINT->cb->getResourceAmount(static_cast(soldItemId)) < r1); + deal->block(LOCPLINT->cb->getResourceAmount(static_cast(soldItemId)) < r1); } else deal->block(false); @@ -1486,7 +1486,7 @@ void CAltarWindow::showAll(SDL_Surface * to) CTradeWindow::showAll(to); if(mode == EMarketMode::ARTIFACT_EXP && arts && arts->commonInfo->src.art) { - artIcon->setFrame(arts->commonInfo->src.art->artType->iconIndex); + artIcon->setFrame(arts->commonInfo->src.art->artType->getIconIndex()); artIcon->showAll(to); int dmp, val; diff --git a/client/windows/CreaturePurchaseCard.cpp b/client/windows/CreaturePurchaseCard.cpp index 4678a6546..d86504776 100644 --- a/client/windows/CreaturePurchaseCard.cpp +++ b/client/windows/CreaturePurchaseCard.cpp @@ -48,13 +48,13 @@ void CreaturePurchaseCard::initCreatureSwitcherButton() void CreaturePurchaseCard::switchCreatureLevel() { OBJECT_CONSTRUCTION_CAPTURING(ACTIVATE + DEACTIVATE + UPDATE + SHOWALL + SHARE_POS); - auto index = vstd::find_pos(upgradesID, creatureOnTheCard->idNumber); + auto index = vstd::find_pos(upgradesID, creatureOnTheCard->getId()); auto nextCreatureId = vstd::circularAt(upgradesID, ++index); creatureOnTheCard = nextCreatureId.toCreature(); picture = std::make_shared(parent->pos.x, parent->pos.y, creatureOnTheCard); creatureClickArea = std::make_shared(Point(parent->pos.x, parent->pos.y), picture, creatureOnTheCard); parent->updateAllSliders(); - cost->set(creatureOnTheCard->cost * slider->getValue()); + cost->set(creatureOnTheCard->getFullRecruitCost() * slider->getValue()); } void CreaturePurchaseCard::initAmountInfo() @@ -78,13 +78,13 @@ void CreaturePurchaseCard::initSlider() void CreaturePurchaseCard::initCostBox() { cost = std::make_shared(Rect(pos.x+2, pos.y + 194, 97, 74), ""); - cost->createItems(creatureOnTheCard->cost); + cost->createItems(creatureOnTheCard->getFullRecruitCost()); } void CreaturePurchaseCard::sliderMoved(int to) { updateAmountInfo(to); - cost->set(creatureOnTheCard->cost * to); + cost->set(creatureOnTheCard->getFullRecruitCost() * to); parent->updateAllSliders(); } diff --git a/client/windows/GUIClasses.cpp b/client/windows/GUIClasses.cpp index fe4beb40d..82c638d46 100644 --- a/client/windows/GUIClasses.cpp +++ b/client/windows/GUIClasses.cpp @@ -135,11 +135,11 @@ void CRecruitmentWindow::select(std::shared_ptr card) else // if slider already at 0 - emulate call to sliderMoved() sliderMoved(maxAmount); - costPerTroopValue->createItems(card->creature->cost); - totalCostValue->createItems(card->creature->cost); + costPerTroopValue->createItems(card->creature->getFullRecruitCost()); + totalCostValue->createItems(card->creature->getFullRecruitCost()); - costPerTroopValue->set(card->creature->cost); - totalCostValue->set(card->creature->cost * maxAmount); + costPerTroopValue->set(card->creature->getFullRecruitCost()); + totalCostValue->set(card->creature->getFullRecruitCost() * maxAmount); //Recruit %s title->setText(boost::str(boost::format(CGI->generaltexth->tcommands[21]) % card->creature->getNamePluralTranslated())); @@ -151,7 +151,7 @@ void CRecruitmentWindow::select(std::shared_ptr card) void CRecruitmentWindow::buy() { - CreatureID crid = selected->creature->idNumber; + CreatureID crid = selected->creature->getId(); SlotID dstslot = dst-> getSlotFor(crid); if(!dstslot.validSlot() && (selected->creature->warMachine == ArtifactID::NONE)) //no available slot @@ -296,7 +296,7 @@ void CRecruitmentWindow::sliderMoved(int to) availableValue->setText(std::to_string(selected->amount - to)); toRecruitValue->setText(std::to_string(to)); - totalCostValue->set(selected->creature->cost * to); + totalCostValue->set(selected->creature->getFullRecruitCost() * to); } CSplitWindow::CSplitWindow(const CCreature * creature, std::function callback_, int leftMin_, int rightMin_, int leftAmount_, int rightAmount_) @@ -463,7 +463,7 @@ CTavernWindow::CTavernWindow(const CGObjectInstance * TavernObj) recruit = std::make_shared(Point(272, 355), "TPTAV01.DEF", CButton::tooltip(), std::bind(&CTavernWindow::recruitb, this), SDLK_RETURN); thiefGuild = std::make_shared(Point(22, 428), "TPTAV02.DEF", CButton::tooltip(CGI->generaltexth->tavernInfo[5]), std::bind(&CTavernWindow::thievesguildb, this), SDLK_t); - if(LOCPLINT->cb->getResourceAmount(Res::GOLD) < GameConstants::HERO_GOLD_COST) //not enough gold + if(LOCPLINT->cb->getResourceAmount(EGameResID::GOLD) < GameConstants::HERO_GOLD_COST) //not enough gold { recruit->addHoverText(CButton::NORMAL, CGI->generaltexth->tavernInfo[0]); //Cannot afford a Hero recruit->block(true); @@ -811,7 +811,7 @@ void CExchangeController::moveArmy(bool leftToRight) source->Slots(), [](const std::pair & s) -> int { - return s.second->getCreatureID().toCreature()->AIValue; + return s.second->getCreatureID().toCreature()->getAIValue(); }); slot = weakestSlot->first; @@ -1093,20 +1093,20 @@ CShipyardWindow::CShipyardWindow(const TResources & cost, int state, int boatTyp bgShip->center(waterCenter); // Create resource icons and costs. - std::string goldValue = std::to_string(cost[Res::GOLD]); - std::string woodValue = std::to_string(cost[Res::WOOD]); + std::string goldValue = std::to_string(cost[EGameResID::GOLD]); + std::string woodValue = std::to_string(cost[EGameResID::WOOD]); goldCost = std::make_shared(118, 294, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE, goldValue); woodCost = std::make_shared(212, 294, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE, woodValue); - goldPic = std::make_shared("RESOURCE", Res::GOLD, 0, 100, 244); - woodPic = std::make_shared("RESOURCE", Res::WOOD, 0, 196, 244); + goldPic = std::make_shared("RESOURCE",GameResID(EGameResID::GOLD), 0, 100, 244); + woodPic = std::make_shared("RESOURCE", GameResID(EGameResID::WOOD), 0, 196, 244); quit = std::make_shared(Point(224, 312), "ICANCEL", CButton::tooltip(CGI->generaltexth->allTexts[599]), std::bind(&CShipyardWindow::close, this), SDLK_ESCAPE); build = std::make_shared(Point(42, 312), "IBUY30", CButton::tooltip(CGI->generaltexth->allTexts[598]), std::bind(&CShipyardWindow::close, this), SDLK_RETURN); build->addCallback(onBuy); - for(Res::ERes i = Res::WOOD; i <= Res::GOLD; vstd::advance(i, 1)) + for(auto i = EGameResID::WOOD; i <= EGameResID::GOLD; vstd::advance(i, 1)) { if(cost[i] > LOCPLINT->cb->getResourceAmount(i)) { @@ -1141,7 +1141,7 @@ void CTransformerWindow::CItem::clickLeft(tribool down, bool previousState) void CTransformerWindow::CItem::update() { - icon->setFrame(parent->army->getCreature(SlotID(id))->idNumber + 2); + icon->setFrame(parent->army->getCreature(SlotID(id))->getId() + 2); } CTransformerWindow::CItem::CItem(CTransformerWindow * parent_, int size_, int id_) @@ -1157,7 +1157,7 @@ CTransformerWindow::CItem::CItem(CTransformerWindow * parent_, int size_, int id pos.x += 45 + (id%3)*83 + id/6*83; pos.y += 109 + (id/3)*98; - icon = std::make_shared("TWCRPORT", parent->army->getCreature(SlotID(id))->idNumber + 2); + icon = std::make_shared("TWCRPORT", parent->army->getCreature(SlotID(id))->getId() + 2); count = std::make_shared(28, 76,FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE, std::to_string(size)); } @@ -1240,7 +1240,7 @@ void CUniversityWindow::CItem::clickLeft(tribool down, bool previousState) if(previousState && (!down)) { if(state() == 2) - GH.pushIntT(parent, ID, LOCPLINT->cb->getResourceAmount(Res::GOLD) >= 2000); + GH.pushIntT(parent, ID, LOCPLINT->cb->getResourceAmount(EGameResID::GOLD) >= 2000); } } @@ -1346,7 +1346,7 @@ CUnivConfirmWindow::CUnivConfirmWindow(CUniversityWindow * owner_, int SKILL, bo icon = std::make_shared("SECSKILL", SKILL*3+3, 0, 211, 51); level = std::make_shared(230, 107, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE, CGI->generaltexth->levels[1]); - costIcon = std::make_shared("RESOURCE", Res::GOLD, 0, 210, 210); + costIcon = std::make_shared("RESOURCE", GameResID(EGameResID::GOLD), 0, 210, 210); cost = std::make_shared(230, 267, FONT_SMALL, ETextAlignment::CENTER, Colors::WHITE, "2000"); std::string hoverText = CGI->generaltexth->allTexts[609]; @@ -1531,7 +1531,7 @@ void CHillFortWindow::updateGarrisons() else//free upgrade - print gold image and "Free" text { slotIcons[i][0]->visible = true; - slotIcons[i][0]->setFrame(Res::GOLD); + slotIcons[i][0]->setFrame(GameResID(EGameResID::GOLD)); slotLabels[i][0]->setText(CGI->generaltexth->allTexts[344]); } } diff --git a/client/windows/QuickRecruitmentWindow.cpp b/client/windows/QuickRecruitmentWindow.cpp index 17c61a2c0..67bf8ad43 100644 --- a/client/windows/QuickRecruitmentWindow.cpp +++ b/client/windows/QuickRecruitmentWindow.cpp @@ -93,7 +93,7 @@ void QuickRecruitmentWindow::maxAllCards(std::vectorsliderMoved(maxAmount); i->slider->moveToMax(); - allAvailableResources -= (i->creatureOnTheCard->cost * maxAmount); + allAvailableResources -= (i->creatureOnTheCard->getFullRecruitCost() * maxAmount); } maxButton->block(allAvailableResources == LOCPLINT->cb->getResourceAmount()); } @@ -105,8 +105,8 @@ void QuickRecruitmentWindow::purchaseUnits() { if(selected->slider->getValue()) { - auto onRecruit = [=](CreatureID id, int count){ LOCPLINT->cb->recruitCreatures(town, town->getUpperArmy(), id, count, selected->creatureOnTheCard->level-1); }; - CreatureID crid = selected->creatureOnTheCard->idNumber; + auto onRecruit = [=](CreatureID id, int count){ LOCPLINT->cb->recruitCreatures(town, town->getUpperArmy(), id, count, selected->creatureOnTheCard->getLevel()-1); }; + CreatureID crid = selected->creatureOnTheCard->getId(); SlotID dstslot = town -> getSlotFor(crid); if(!dstslot.validSlot()) continue; @@ -129,7 +129,7 @@ void QuickRecruitmentWindow::updateAllSliders() { auto allAvailableResources = LOCPLINT->cb->getResourceAmount(); for(auto i : boost::adaptors::reverse(cards)) - allAvailableResources -= (i->creatureOnTheCard->cost * i->slider->getValue()); + allAvailableResources -= (i->creatureOnTheCard->getFullRecruitCost() * i->slider->getValue()); for(auto i : cards) { si32 maxAmount = i->creatureOnTheCard->maxAmount(allAvailableResources); diff --git a/include/vcmi/Creature.h b/include/vcmi/Creature.h index d29fa4480..e6e72e188 100644 --- a/include/vcmi/Creature.h +++ b/include/vcmi/Creature.h @@ -15,6 +15,8 @@ VCMI_LIB_NAMESPACE_BEGIN class CreatureID; +class ResourceSet; +enum class EGameResID : int8_t; class DLL_LINKAGE Creature : public EntityWithBonuses { @@ -50,7 +52,10 @@ public: virtual int32_t getBaseSpeed() const = 0; virtual int32_t getBaseShots() const = 0; - virtual int32_t getCost(int32_t resIndex) const = 0; + virtual int32_t getRecruitCost(Identifier resIndex) const = 0; + virtual ResourceSet getFullRecruitCost() const = 0; + + virtual bool hasUpgrades() const = 0; virtual bool isDoubleWide() const = 0; }; diff --git a/include/vcmi/Entity.h b/include/vcmi/Entity.h index ec64feaad..b34d692f3 100644 --- a/include/vcmi/Entity.h +++ b/include/vcmi/Entity.h @@ -14,6 +14,12 @@ VCMI_LIB_NAMESPACE_BEGIN class IBonusBearer; +class DLL_LINKAGE WithBonuses +{ +public: + virtual const IBonusBearer * getBonusBearer() const = 0; +}; + class DLL_LINKAGE Entity { public: @@ -38,10 +44,8 @@ public: }; template -class DLL_LINKAGE EntityWithBonuses : public EntityT +class DLL_LINKAGE EntityWithBonuses : public EntityT, public WithBonuses { -public: - virtual const IBonusBearer * accessBonuses() const = 0; }; VCMI_LIB_NAMESPACE_END diff --git a/lib/CArtHandler.cpp b/lib/CArtHandler.cpp index 3555326e0..2b6da96a7 100644 --- a/lib/CArtHandler.cpp +++ b/lib/CArtHandler.cpp @@ -77,7 +77,7 @@ ArtifactID CArtifact::getId() const return id; } -const IBonusBearer * CArtifact::accessBonuses() const +const IBonusBearer * CArtifact::getBonusBearer() const { return this; } diff --git a/lib/CArtHandler.h b/lib/CArtHandler.h index b56ffb1d7..8f669c32c 100644 --- a/lib/CArtHandler.h +++ b/lib/CArtHandler.h @@ -69,7 +69,7 @@ public: std::string getJsonKey() const override; void registerIcons(const IconRegistar & cb) const override; ArtifactID getId() const override; - virtual const IBonusBearer * accessBonuses() const override; + virtual const IBonusBearer * getBonusBearer() const override; std::string getDescriptionTranslated() const override; std::string getEventTranslated() const override; diff --git a/lib/CCreatureHandler.cpp b/lib/CCreatureHandler.cpp index b1fabc7a3..6e22a1a46 100644 --- a/lib/CCreatureHandler.cpp +++ b/lib/CCreatureHandler.cpp @@ -64,7 +64,7 @@ CreatureID CCreature::getId() const return idNumber; } -const IBonusBearer * CCreature::accessBonuses() const +const IBonusBearer * CCreature::getBonusBearer() const { return this; } @@ -162,7 +162,7 @@ int32_t CCreature::getBaseShots() const return getExportedBonusList().valOfBonuses(SELECTOR); } -int32_t CCreature::getCost(int32_t resIndex) const +int32_t CCreature::getRecruitCost(GameResID resIndex) const { if(resIndex >= 0 && resIndex < cost.size()) return cost[resIndex]; @@ -170,6 +170,16 @@ int32_t CCreature::getCost(int32_t resIndex) const return 0; } +TResources CCreature::getFullRecruitCost() const +{ + return cost; +} + +bool CCreature::hasUpgrades() const +{ + return !upgrades.empty(); +} + std::string CCreature::getNameTranslated() const { return getNameSingularTranslated(); @@ -307,7 +317,7 @@ void CCreature::addBonus(int val, Bonus::BonusType type, int subtype) bool CCreature::isMyUpgrade(const CCreature *anotherCre) const { //TODO upgrade of upgrade? - return vstd::contains(upgrades, anotherCre->idNumber); + return vstd::contains(upgrades, anotherCre->getId()); } bool CCreature::valid() const @@ -614,7 +624,7 @@ CCreature * CCreatureHandler::loadFromJson(const std::string & scope, const Json JsonDeserializer handler(nullptr, node); cre->serializeJson(handler); - cre->cost = Res::ResourceSet(node["cost"]); + cre->cost = ResourceSet(node["cost"]); VLC->generaltexth->registerString(scope, cre->getNameSingularTextID(), node["name"]["singular"].String()); VLC->generaltexth->registerString(scope, cre->getNamePluralTextID(), node["name"]["plural"].String()); @@ -647,18 +657,18 @@ CCreature * CCreatureHandler::loadFromJson(const std::string & scope, const Json JsonNode conf; conf.setMeta(scope); - VLC->objtypeh->loadSubObject(cre->identifier, conf, Obj::MONSTER, cre->idNumber.num); + VLC->objtypeh->loadSubObject(cre->identifier, conf, Obj::MONSTER, cre->getId().num); if (!cre->advMapDef.empty()) { JsonNode templ; templ["animation"].String() = cre->advMapDef; templ.setMeta(scope); - VLC->objtypeh->getHandlerFor(Obj::MONSTER, cre->idNumber.num)->addTemplate(templ); + VLC->objtypeh->getHandlerFor(Obj::MONSTER, cre->getId().num)->addTemplate(templ); } // object does not have any templates - this is not usable object (e.g. pseudo-creature like Arrow Tower) - if (VLC->objtypeh->getHandlerFor(Obj::MONSTER, cre->idNumber.num)->getTemplates().empty()) - VLC->objtypeh->removeSubObject(Obj::MONSTER, cre->idNumber.num); + if (VLC->objtypeh->getHandlerFor(Obj::MONSTER, cre->getId().num)->getTemplates().empty()) + VLC->objtypeh->removeSubObject(Obj::MONSTER, cre->getId().num); }); return cre; @@ -1335,7 +1345,7 @@ CreatureID CCreatureHandler::pickRandomMonster(CRandomGenerator & rand, int tier { do { - r = (*RandomGeneratorUtil::nextItem(objects, rand))->idNumber; + r = (*RandomGeneratorUtil::nextItem(objects, rand))->getId(); } while (objects[r] && objects[r]->special); // find first "not special" creature } else @@ -1347,7 +1357,7 @@ CreatureID CCreatureHandler::pickRandomMonster(CRandomGenerator & rand, int tier assert(b->getNodeType() == CBonusSystemNode::CREATURE); const auto * crea = dynamic_cast(b); if(crea && !crea->special) - allowed.push_back(crea->idNumber); + allowed.push_back(crea->getId()); } if(allowed.empty()) diff --git a/lib/CCreatureHandler.h b/lib/CCreatureHandler.h index 240e3d286..535978c72 100644 --- a/lib/CCreatureHandler.h +++ b/lib/CCreatureHandler.h @@ -9,9 +9,6 @@ */ #pragma once -#include -#include - #include "HeroBonus.h" #include "ConstTransitivePtr.h" #include "ResourceSet.h" @@ -21,6 +18,9 @@ #include "CRandomGenerator.h" #include "Color.h" +#include +#include + VCMI_LIB_NAMESPACE_BEGIN class CLegacyConfigParser; @@ -37,7 +37,6 @@ class DLL_LINKAGE CCreature : public Creature, public CBonusSystemNode std::string getNameTranslated() const override; std::string getNameTextID() const override; -public: CreatureID idNumber; TFaction faction = 0; @@ -45,17 +44,22 @@ public: //stats that are not handled by bonus system ui32 fightValue, AIValue, growth, hordeGrowth; - ui32 ammMin, ammMax; // initial size of stack of these creatures on adventure map (if not set in editor) bool doubleWide = false; - bool special = true; // Creature is not available normally (war machines, commanders, several unused creatures, etc + + si32 iconIndex = -1; // index of icon in files like twcrport TResources cost; //cost[res_id] - amount of that resource required to buy creature from dwelling + +public: + ui32 ammMin, ammMax; // initial size of stack of these creatures on adventure map (if not set in editor) + + bool special = true; // Creature is not available normally (war machines, commanders, several unused creatures, etc + std::set upgrades; // IDs of creatures to which this creature can be upgraded std::string animDefName; // creature animation used during battles std::string advMapDef; //for new creatures only, image for adventure map - si32 iconIndex = -1; // index of icon in files like twcrport /// names of files with appropriate icons. Used only during loading std::string smallIconName; @@ -168,7 +172,7 @@ public: std::string getJsonKey() const override; void registerIcons(const IconRegistar & cb) const override; CreatureID getId() const override; - virtual const IBonusBearer * accessBonuses() const override; + virtual const IBonusBearer * getBonusBearer() const override; uint32_t getMaxHealth() const override; int32_t getAdvMapAmountMin() const override; @@ -189,8 +193,10 @@ public: int32_t getBaseSpeed() const override; int32_t getBaseShots() const override; - int32_t getCost(int32_t resIndex) const override; + int32_t getRecruitCost(GameResID resIndex) const override; + TResources getFullRecruitCost() const override; bool isDoubleWide() const override; //returns true if unit is double wide on battlefield + bool hasUpgrades() const override; bool isGood () const; bool isEvil () const; diff --git a/lib/CCreatureSet.cpp b/lib/CCreatureSet.cpp index 6db38dfa0..7e39e07b0 100644 --- a/lib/CCreatureSet.cpp +++ b/lib/CCreatureSet.cpp @@ -590,12 +590,12 @@ bool CCreatureSet::canBeMergedWith(const CCreatureSet &cs, bool allowMergingStac //get types of creatures that need their own slot for(const auto & elem : cs.stacks) if ((j = cres.getSlotFor(elem.second->type)).validSlot()) - cres.addToSlot(j, elem.second->type->idNumber, 1, true); //merge if possible - //cres.addToSlot(elem.first, elem.second->type->idNumber, 1, true); + cres.addToSlot(j, elem.second->type->getId(), 1, true); //merge if possible + //cres.addToSlot(elem.first, elem.second->type->getId(), 1, true); for(const auto & elem : stacks) { if ((j = cres.getSlotFor(elem.second->type)).validSlot()) - cres.addToSlot(j, elem.second->type->idNumber, 1, true); //merge if possible + cres.addToSlot(j, elem.second->type->getId(), 1, true); //merge if possible else return false; //no place found } @@ -706,7 +706,7 @@ int CStackInstance::getExpRank() const { if (!VLC->settings()->getBoolean(EGameSettings::MODULE_STACK_EXPERIENCE)) return 0; - int tier = type->level; + int tier = type->getLevel(); if (vstd::iswithin(tier, 1, 7)) { for(int i = static_cast(VLC->creh->expRanks[tier].size()) - 2; i > -1; --i) //sic! @@ -729,7 +729,7 @@ int CStackInstance::getExpRank() const int CStackInstance::getLevel() const { - return std::max(1, static_cast(type->level)); + return std::max(1, static_cast(type->getLevel())); } si32 CStackInstance::magicResistance() const @@ -741,7 +741,7 @@ si32 CStackInstance::magicResistance() const void CStackInstance::giveStackExp(TExpType exp) { - int level = type->level; + int level = type->getLevel(); if (!vstd::iswithin(level, 1, 7)) level = 0; @@ -816,7 +816,7 @@ bool CStackInstance::valid(bool allowUnrandomized) const bool isRand = (idRand != -1); if(!isRand) { - return (type && type == VLC->creh->objects[type->idNumber]); + return (type && type == VLC->creh->objects[type->getId()]); } else return allowUnrandomized; @@ -852,7 +852,7 @@ void CStackInstance::deserializationFix() CreatureID CStackInstance::getCreatureID() const { if(type) - return type->idNumber; + return type->getId(); else return CreatureID::NONE; } @@ -865,7 +865,7 @@ std::string CStackInstance::getName() const ui64 CStackInstance::getPower() const { assert(type); - return type->AIValue * count; + return type->getAIValue() * count; } ArtBearer::ArtBearer CStackInstance::bearerType() const diff --git a/lib/CCreatureSet.h b/lib/CCreatureSet.h index 89e028027..60a83dab8 100644 --- a/lib/CCreatureSet.h +++ b/lib/CCreatureSet.h @@ -43,7 +43,7 @@ public: { if(h.saving) { - CreatureID idNumber = type ? type->idNumber : CreatureID(CreatureID::NONE); + auto idNumber = type ? type->getId() : CreatureID(CreatureID::NONE); h & idNumber; } else @@ -51,7 +51,7 @@ public: CreatureID idNumber; h & idNumber; if(idNumber != CreatureID::NONE) - setType(VLC->creh->objects[idNumber]); + setType(dynamic_cast(VLC->creatures()->getByIndex(idNumber))); else type = nullptr; } diff --git a/lib/CGameInfoCallback.cpp b/lib/CGameInfoCallback.cpp index 79cf43a9c..939ff09c3 100644 --- a/lib/CGameInfoCallback.cpp +++ b/lib/CGameInfoCallback.cpp @@ -37,7 +37,7 @@ PlayerColor CGameInfoCallback::getOwner(ObjectInstanceID heroID) const return obj->tempOwner; } -int CGameInfoCallback::getResource(PlayerColor Player, Res::ERes which) const +int CGameInfoCallback::getResource(PlayerColor Player, GameResID which) const { const PlayerState *p = getPlayerState(Player); ERROR_RET_VAL_IF(!p, "No player info!", -1); @@ -323,9 +323,9 @@ bool CGameInfoCallback::getHeroInfo(const CGObjectInstance * hero, InfoAboutHero for(auto & elem : info.army) { - if(static_cast(elem.second.type->AIValue) > maxAIValue) + if(static_cast(elem.second.type->getAIValue()) > maxAIValue) { - maxAIValue = elem.second.type->AIValue; + maxAIValue = elem.second.type->getAIValue(); mostStrong = elem.second.type; } } @@ -359,9 +359,9 @@ bool CGameInfoCallback::getHeroInfo(const CGObjectInstance * hero, InfoAboutHero for(auto creature : VLC->creh->objects) { - if(static_cast(creature->faction) == factionIndex && static_cast(creature->AIValue) > maxAIValue) + if(static_cast(creature->getFactionIndex()) == factionIndex && static_cast(creature->getAIValue()) > maxAIValue) { - maxAIValue = creature->AIValue; + maxAIValue = creature->getAIValue(); mostStrong = creature; } } @@ -860,7 +860,7 @@ const CGTownInstance* CPlayerSpecificInfoCallback::getTownBySerial(int serialId) return p->towns[serialId]; } -int CPlayerSpecificInfoCallback::getResourceAmount(Res::ERes type) const +int CPlayerSpecificInfoCallback::getResourceAmount(GameResID type) const { //boost::shared_lock lock(*gs->mx); ERROR_RET_VAL_IF(!player, "Applicable only for player callbacks", -1); diff --git a/lib/CGameInfoCallback.h b/lib/CGameInfoCallback.h index 220acb9ac..9d23c4965 100644 --- a/lib/CGameInfoCallback.h +++ b/lib/CGameInfoCallback.h @@ -10,7 +10,7 @@ #pragma once #include "int3.h" -#include "ResourceSet.h" // for Res::ERes +#include "ResourceSet.h" // for Res #include "battle/CCallbackBase.h" VCMI_LIB_NAMESPACE_BEGIN @@ -58,7 +58,7 @@ public: //player virtual const Player * getPlayer(PlayerColor color) const = 0; -// virtual int getResource(PlayerColor Player, Res::ERes which) const = 0; +// virtual int getResource(PlayerColor Player, EGameResID which) const = 0; // bool isVisible(int3 pos) const; // PlayerRelations::PlayerRelations getPlayerRelations(PlayerColor color1, PlayerColor color2) const; // void getThievesGuildInfo(SThievesGuildInfo & thi, const CGObjectInstance * obj); //get thieves' guild info obtainable while visiting given object @@ -148,7 +148,7 @@ public: //player const Player * getPlayer(PlayerColor color) const override; virtual const PlayerState * getPlayerState(PlayerColor color, bool verbose = true) const; - virtual int getResource(PlayerColor Player, Res::ERes which) const; + virtual int getResource(PlayerColor Player, GameResID which) const; virtual PlayerRelations::PlayerRelations getPlayerRelations(PlayerColor color1, PlayerColor color2) const; virtual void getThievesGuildInfo(SThievesGuildInfo & thi, const CGObjectInstance * obj); //get thieves' guild info obtainable while visiting given object virtual EPlayerStatus::EStatus getPlayerStatus(PlayerColor player, bool verbose = true) const; //-1 if no such player @@ -245,7 +245,7 @@ public: virtual std::vector getMyObjects() const; //returns all objects flagged by belonging player virtual std::vector getMyQuests() const; - virtual int getResourceAmount(Res::ERes type) const; + virtual int getResourceAmount(GameResID type) const; virtual TResources getResourceAmount() const; virtual std::shared_ptr> getVisibilityMap() const; //returns visibility map //virtual const PlayerSettings * getPlayerSettings(PlayerColor color) const; diff --git a/lib/CGameState.cpp b/lib/CGameState.cpp index 615d23283..d6cff0d7e 100644 --- a/lib/CGameState.cpp +++ b/lib/CGameState.cpp @@ -293,7 +293,7 @@ void MetaString::addCreReplacement(const CreatureID & id, TQuantity count) //add void MetaString::addReplacement(const CStackBasicDescriptor & stack) { assert(stack.type); //valid type - addCreReplacement(stack.type->idNumber, stack.count); + addCreReplacement(stack.type->getId(), stack.count); } static CGObjectInstance * createObject(const Obj & id, int subid, const int3 & pos, const PlayerColor & owner) @@ -1443,10 +1443,14 @@ void CGameState::initStartingResources() res.push_back(chosenBonus->info1); break; case 0xFD: //wood+ore - res.push_back(Res::WOOD); res.push_back(Res::ORE); + res.push_back(GameResID(EGameResID::WOOD)); + res.push_back(GameResID(EGameResID::ORE)); break; case 0xFE: //rare - res.push_back(Res::MERCURY); res.push_back(Res::SULFUR); res.push_back(Res::CRYSTAL); res.push_back(Res::GEMS); + res.push_back(GameResID(EGameResID::MERCURY)); + res.push_back(GameResID(EGameResID::SULFUR)); + res.push_back(GameResID(EGameResID::CRYSTAL)); + res.push_back(GameResID(EGameResID::GEMS)); break; default: assert(0); @@ -1664,16 +1668,16 @@ void CGameState::initStartingBonus() switch(scenarioOps->playerInfos[elem.first].bonus) { case PlayerSettings::GOLD: - elem.second.resources[Res::GOLD] += getRandomGenerator().nextInt(5, 10) * 100; + elem.second.resources[EGameResID::GOLD] += getRandomGenerator().nextInt(5, 10) * 100; break; case PlayerSettings::RESOURCE: { - int res = (*VLC->townh)[scenarioOps->playerInfos[elem.first].castle]->town->primaryRes; - if(res == Res::WOOD_AND_ORE) + auto res = (*VLC->townh)[scenarioOps->playerInfos[elem.first].castle]->town->primaryRes; + if(res == EGameResID::WOOD_AND_ORE) { int amount = getRandomGenerator().nextInt(5, 10); - elem.second.resources[Res::WOOD] += amount; - elem.second.resources[Res::ORE] += amount; + elem.second.resources[EGameResID::WOOD] += amount; + elem.second.resources[EGameResID::ORE] += amount; } else { @@ -2016,14 +2020,14 @@ UpgradeInfo CGameState::fillUpgradeInfo(const CStackInstance &stack) const t = dynamic_cast(stack.armyObj); else if(h) { //hero specialty - TConstBonusListPtr lista = h->getBonuses(Selector::typeSubtype(Bonus::SPECIAL_UPGRADE, base->idNumber)); + TConstBonusListPtr lista = h->getBonuses(Selector::typeSubtype(Bonus::SPECIAL_UPGRADE, base->getId())); for(const auto & it : *lista) { auto nid = CreatureID(it->additionalInfo[0]); - if (nid != base->idNumber) //in very specific case the upgrade is available by default (?) + if (nid != base->getId()) //in very specific case the upgrade is available by default (?) { ret.newID.push_back(nid); - ret.cost.push_back(VLC->creh->objects[nid]->cost - base->cost); + ret.cost.push_back(nid.toCreature()->getFullRecruitCost() - base->getFullRecruitCost()); } } t = h->visitedTown; @@ -2032,14 +2036,14 @@ UpgradeInfo CGameState::fillUpgradeInfo(const CStackInstance &stack) const { for(const CGTownInstance::TCreaturesSet::value_type & dwelling : t->creatures) { - if (vstd::contains(dwelling.second, base->idNumber)) //Dwelling with our creature + if (vstd::contains(dwelling.second, base->getId())) //Dwelling with our creature { for(const auto & upgrID : dwelling.second) { if(vstd::contains(base->upgrades, upgrID)) //possible upgrade { ret.newID.push_back(upgrID); - ret.cost.push_back(VLC->creh->objects[upgrID]->cost - base->cost); + ret.cost.push_back(upgrID.toCreature()->getFullRecruitCost() - base->getFullRecruitCost()); } } } @@ -2050,19 +2054,19 @@ UpgradeInfo CGameState::fillUpgradeInfo(const CStackInstance &stack) const if(h && map->getTile(h->visitablePos()).visitableObjects.front()->ID == Obj::HILL_FORT) { static const int costModifiers[] = {0, 25, 50, 75, 100}; //we get cheaper upgrades depending on level - const int costModifier = costModifiers[std::min(std::max((int)base->level - 1, 0), ARRAY_COUNT(costModifiers) - 1)]; + const int costModifier = costModifiers[std::min(std::max((int)base->getLevel() - 1, 0), ARRAY_COUNT(costModifiers) - 1)]; for(const auto & nid : base->upgrades) { ret.newID.push_back(nid); - ret.cost.push_back((VLC->creh->objects[nid]->cost - base->cost) * costModifier / 100); + ret.cost.push_back((nid.toCreature()->getFullRecruitCost() - base->getFullRecruitCost()) * costModifier / 100); } } if(!ret.newID.empty()) - ret.oldID = base->idNumber; + ret.oldID = base->getId(); - for (Res::ResourceSet &cost : ret.cost) + for (ResourceSet &cost : ret.cost) cost.positive(); //upgrade cost can't be negative, ignore missing resources return ret; @@ -2346,7 +2350,7 @@ bool CGameState::checkForVictory(const PlayerColor & player, const EventConditio && (ai = dynamic_cast(object.get()))) //contains army { for(const auto & elem : ai->Slots()) //iterate through army - if(elem.second->type->idNumber == condition.objectType) //it's searched creature + if(elem.second->type->getId() == condition.objectType) //it's searched creature total += elem.second->count; } } @@ -2584,7 +2588,7 @@ struct statsHLP //Heroes can produce gold as well - skill, specialty or arts for(const auto & h : ps->heroes) { - totalIncome += h->valOfBonuses(Selector::typeSubtype(Bonus::GENERATE_RESOURCE, Res::GOLD)); + totalIncome += h->valOfBonuses(Selector::typeSubtype(Bonus::GENERATE_RESOURCE, GameResID(EGameResID::GOLD))); if(!heroOrTown) heroOrTown = h; @@ -2593,7 +2597,7 @@ struct statsHLP //Add town income of all towns for(const auto & t : ps->towns) { - totalIncome += t->dailyIncome()[Res::GOLD]; + totalIncome += t->dailyIncome()[EGameResID::GOLD]; if(!heroOrTown) heroOrTown = t; @@ -2618,7 +2622,7 @@ struct statsHLP const auto * mine = dynamic_cast(object); assert(mine); - if (mine->producedResource == Res::GOLD) + if (mine->producedResource == EGameResID::GOLD) totalIncome += mine->producedQuantity; } } @@ -2677,15 +2681,15 @@ void CGameState::obtainPlayersStats(SThievesGuildInfo & tgi, int level) } if(level >= 2) //gold { - FILL_FIELD(gold, g->second.resources[Res::GOLD]) + FILL_FIELD(gold, g->second.resources[EGameResID::GOLD]) } if(level >= 2) //wood & ore { - FILL_FIELD(woodOre, g->second.resources[Res::WOOD] + g->second.resources[Res::ORE]) + FILL_FIELD(woodOre, g->second.resources[EGameResID::WOOD] + g->second.resources[EGameResID::ORE]) } if(level >= 3) //mercury, sulfur, crystal, gems { - FILL_FIELD(mercSulfCrystGems, g->second.resources[Res::MERCURY] + g->second.resources[Res::SULFUR] + g->second.resources[Res::CRYSTAL] + g->second.resources[Res::GEMS]) + FILL_FIELD(mercSulfCrystGems, g->second.resources[EGameResID::MERCURY] + g->second.resources[EGameResID::SULFUR] + g->second.resources[EGameResID::CRYSTAL] + g->second.resources[EGameResID::GEMS]) } if(level >= 3) //obelisks found { @@ -2744,8 +2748,8 @@ void CGameState::obtainPlayersStats(SThievesGuildInfo & tgi, int level) { for(const auto & it : elem->Slots()) { - int toCmp = it.second->type->idNumber; //ID of creature we should compare with the best one - if(bestCre == -1 || VLC->creh->objects[bestCre]->AIValue < VLC->creh->objects[toCmp]->AIValue) + int toCmp = it.second->type->getId(); //ID of creature we should compare with the best one + if(bestCre == -1 || VLC->creh->objects[bestCre]->getAIValue() < VLC->creh->objects[toCmp]->getAIValue()) { bestCre = toCmp; } @@ -3138,7 +3142,7 @@ void InfoAboutTown::initFromTown(const CGTownInstance *t, bool detailed) //include details about hero details = new Details(); TResources income = t->dailyIncome(); - details->goldIncome = income[Res::GOLD]; + details->goldIncome = income[EGameResID::GOLD]; details->customRes = t->hasBuilt(BuildingID::RESOURCE_SILO); details->hallLevel = t->hallLevel(); details->garrisonedHero = t->garrisonHero; @@ -3169,12 +3173,12 @@ int ArmyDescriptor::getStrength() const if(isDetailed) { for(const auto & elem : *this) - ret += elem.second.type->AIValue * elem.second.count; + ret += elem.second.type->getAIValue() * elem.second.count; } else { for(const auto & elem : *this) - ret += elem.second.type->AIValue * CCreature::estimateCreatureCount(elem.second.count); + ret += elem.second.type->getAIValue() * CCreature::estimateCreatureCount(elem.second.count); } return static_cast(ret); } diff --git a/lib/CGameStateFwd.h b/lib/CGameStateFwd.h index c617d4a6f..b1cd401e7 100644 --- a/lib/CGameStateFwd.h +++ b/lib/CGameStateFwd.h @@ -164,7 +164,7 @@ private: { } - si32 intValue; // uses EResult + si32 intValue; // uses EResultult }; /*static std::ostream & operator<<(std::ostream & os, const EVictoryLossCheckResult & victoryLossCheckResult) diff --git a/lib/CHeroHandler.cpp b/lib/CHeroHandler.cpp index 5b74115ff..58e3fee42 100644 --- a/lib/CHeroHandler.cpp +++ b/lib/CHeroHandler.cpp @@ -529,7 +529,7 @@ static std::vector> createCreatureSpecialty(CreatureID ba for(CreatureID cid : targets) { const CCreature &specCreature = *VLC->creh->objects[cid]; - int stepSize = specCreature.level ? specCreature.level : 5; + int stepSize = specCreature.getLevel() ? specCreature.getLevel() : 5; { std::shared_ptr bonus = std::make_shared(); diff --git a/lib/CPlayerState.cpp b/lib/CPlayerState.cpp index b73e9b1eb..0e1279453 100644 --- a/lib/CPlayerState.cpp +++ b/lib/CPlayerState.cpp @@ -86,7 +86,7 @@ bool PlayerState::isHuman() const return human; } -const IBonusBearer * PlayerState::accessBonuses() const +const IBonusBearer * PlayerState::getBonusBearer() const { return this; } diff --git a/lib/CPlayerState.h b/lib/CPlayerState.h index 357f59e88..70a378cae 100644 --- a/lib/CPlayerState.h +++ b/lib/CPlayerState.h @@ -48,7 +48,7 @@ public: PlayerColor getId() const override; TeamID getTeam() const override; bool isHuman() const override; - const IBonusBearer * accessBonuses() const override; + const IBonusBearer * getBonusBearer() const override; int getResourceAmount(int type) const override; int32_t getIndex() const override; diff --git a/lib/CStack.cpp b/lib/CStack.cpp index 44439c615..45ef7636c 100644 --- a/lib/CStack.cpp +++ b/lib/CStack.cpp @@ -88,7 +88,7 @@ ui32 CStack::level() const if(base) return base->getLevel(); //creature or commander else - return std::max(1, static_cast(getCreature()->level)); //war machine, clone etc + return std::max(1, static_cast(getCreature()->getLevel())); //war machine, clone etc } si32 CStack::magicResistance() const @@ -342,7 +342,7 @@ bool CStack::unitHasAmmoCart(const battle::Unit * unit) const { for(const CStack * st : battle->stacks) { - if(battle->battleMatchOwner(st, unit, true) && st->getCreature()->idNumber == CreatureID::AMMO_CART) + if(battle->battleMatchOwner(st, unit, true) && st->getCreature()->getId() == CreatureID::AMMO_CART) { return st->alive(); } diff --git a/lib/CTownHandler.cpp b/lib/CTownHandler.cpp index 723ca2f15..11fe60c45 100644 --- a/lib/CTownHandler.cpp +++ b/lib/CTownHandler.cpp @@ -24,6 +24,7 @@ #include "mapObjects/CObjectClassesHandler.h" #include "mapObjects/CObjectHandler.h" #include "HeroBonus.h" +#include "ResourceSet.h" VCMI_LIB_NAMESPACE_BEGIN @@ -635,21 +636,21 @@ void CTownHandler::loadBuilding(CTown * town, const std::string & stringID, cons if(!ret->produce.nonZero()) { switch (ret->bid) { - break; case BuildingID::VILLAGE_HALL: ret->produce[Res::GOLD] = 500; - break; case BuildingID::TOWN_HALL : ret->produce[Res::GOLD] = 1000; - break; case BuildingID::CITY_HALL : ret->produce[Res::GOLD] = 2000; - break; case BuildingID::CAPITOL : ret->produce[Res::GOLD] = 4000; - break; case BuildingID::GRAIL : ret->produce[Res::GOLD] = 5000; + break; case BuildingID::VILLAGE_HALL: ret->produce[EGameResID::GOLD] = 500; + break; case BuildingID::TOWN_HALL : ret->produce[EGameResID::GOLD] = 1000; + break; case BuildingID::CITY_HALL : ret->produce[EGameResID::GOLD] = 2000; + break; case BuildingID::CAPITOL : ret->produce[EGameResID::GOLD] = 4000; + break; case BuildingID::GRAIL : ret->produce[EGameResID::GOLD] = 5000; break; case BuildingID::RESOURCE_SILO : { - switch (ret->town->primaryRes) + switch (ret->town->primaryRes.toEnum()) { - case Res::GOLD: + case EGameResID::GOLD: ret->produce[ret->town->primaryRes] = 500; break; - case Res::WOOD_AND_ORE: - ret->produce[Res::WOOD] = 1; - ret->produce[Res::ORE] = 1; + case EGameResID::WOOD_AND_ORE: + ret->produce[EGameResID::WOOD] = 1; + ret->produce[EGameResID::ORE] = 1; break; default: ret->produce[ret->town->primaryRes] = 1; @@ -880,9 +881,9 @@ void CTownHandler::loadTown(CTown * town, const JsonNode & source) { const auto * resIter = boost::find(GameConstants::RESOURCE_NAMES, source["primaryResource"].String()); if(resIter == std::end(GameConstants::RESOURCE_NAMES)) - town->primaryRes = Res::WOOD_AND_ORE; //Wood + Ore + town->primaryRes = GameResID(EGameResID::WOOD_AND_ORE); //Wood + Ore else - town->primaryRes = static_cast(resIter - std::begin(GameConstants::RESOURCE_NAMES)); + town->primaryRes = GameResID(resIter - std::begin(GameConstants::RESOURCE_NAMES)); warMachinesToLoad[town] = source["warMachine"]; diff --git a/lib/CTownHandler.h b/lib/CTownHandler.h index 54681f9c7..46f65d3a8 100644 --- a/lib/CTownHandler.h +++ b/lib/CTownHandler.h @@ -271,7 +271,7 @@ public: // should be removed at least from configs in favor of auto-detection std::map hordeLvl; //[0] - first horde building creature level; [1] - second horde building (-1 if not present) ui32 mageLevel; //max available mage guild level - ui16 primaryRes; + GameResID primaryRes; ArtifactID warMachine; SpellID moatAbility; // default chance for hero of specific class to appear in tavern, if field "tavern" was not set diff --git a/lib/GameConstants.h b/lib/GameConstants.h index 1a37d494f..fc5152e4b 100644 --- a/lib/GameConstants.h +++ b/lib/GameConstants.h @@ -205,6 +205,11 @@ public: bool operator > (const BaseForID & b) const { return num > b.num; } BaseForID & operator++() { ++num; return *this; } + + operator NumericType() const + { + return num; + } }; template < typename T> @@ -267,6 +272,11 @@ public: ++num; return ret; } + + operator NumericType() const + { + return num; + } }; diff --git a/lib/HeroBonus.cpp b/lib/HeroBonus.cpp index 1887de59b..28b4f717e 100644 --- a/lib/HeroBonus.cpp +++ b/lib/HeroBonus.cpp @@ -1775,7 +1775,7 @@ BonusParams::BonusParams(std::string deprecatedTypeStr, std::string deprecatedSu else if(deprecatedSubtype == SecondarySkill::ESTATES || deprecatedSubtypeStr == "skill.estates") { type = Bonus::GENERATE_RESOURCE; - subtype = Res::GOLD; + subtype = GameResID(EGameResID::GOLD); subtypeRelevant = true; } else if(deprecatedSubtype == SecondarySkill::AIR_MAGIC || deprecatedSubtypeStr == "skill.airMagic") @@ -2380,7 +2380,7 @@ CreatureFactionLimiter::CreatureFactionLimiter(): ILimiter::EDecision CreatureFactionLimiter::limit(const BonusLimitationContext &context) const { const CCreature *c = retrieveCreature(&context.node); - auto accept = c && c->faction == faction; + auto accept = c && c->getFactionIndex() == faction; return accept ? ILimiter::EDecision::ACCEPT : ILimiter::EDecision::DISCARD; //drop bonus for non-creatures or non-native residents } @@ -2731,7 +2731,7 @@ std::shared_ptr TimesStackLevelUpdater::createUpdatedBonus(const std::sha //otherwise we'd end up multiplying twice if(stack.base == nullptr) { - int level = stack.type->level; + int level = stack.type->getLevel(); std::shared_ptr newBonus = std::make_shared(*b); newBonus->val *= level; return newBonus; diff --git a/lib/IGameCallback.h b/lib/IGameCallback.h index 26b84a39d..a6c6eccba 100644 --- a/lib/IGameCallback.h +++ b/lib/IGameCallback.h @@ -93,7 +93,7 @@ public: virtual void showGarrisonDialog(ObjectInstanceID upobj, ObjectInstanceID hid, bool removableUnits) =0; //cb will be called when player closes garrison window virtual void showTeleportDialog(TeleportDialog *iw) =0; virtual void showThievesGuildWindow(PlayerColor player, ObjectInstanceID requestingObjId) =0; - virtual void giveResource(PlayerColor player, Res::ERes which, int val)=0; + virtual void giveResource(PlayerColor player, GameResID which, int val)=0; virtual void giveResources(PlayerColor player, TResources resources)=0; virtual void giveCreatures(const CArmedInstance *objid, const CGHeroInstance * h, const CCreatureSet &creatures, bool remove) =0; diff --git a/lib/NetPacksLib.cpp b/lib/NetPacksLib.cpp index 6c46d04d2..f3d876098 100644 --- a/lib/NetPacksLib.cpp +++ b/lib/NetPacksLib.cpp @@ -1759,7 +1759,7 @@ void RebalanceStacks::applyGs(CGameState * gs) else //split stack to an empty slot { src.army->changeStackCount(src.slot, -count); - dst.army->addToSlot(dst.slot, srcType->idNumber, count, false); + dst.army->addToSlot(dst.slot, srcType->getId(), count, false); if (stackExp) dst.army->setStackExp(dst.slot, src.army->getStackExperience(src.slot)); } @@ -2508,7 +2508,7 @@ void YourTurn::applyGs(CGameState * gs) const Component::Component(const CStackBasicDescriptor & stack) : id(EComponentType::CREATURE) - , subtype(stack.type->idNumber) + , subtype(stack.type->getId()) , val(stack.count) { } diff --git a/lib/ResourceSet.cpp b/lib/ResourceSet.cpp index b36a3d0b5..8603fbc84 100644 --- a/lib/ResourceSet.cpp +++ b/lib/ResourceSet.cpp @@ -19,26 +19,26 @@ VCMI_LIB_NAMESPACE_BEGIN -Res::ResourceSet::ResourceSet(const JsonNode & node) +ResourceSet::ResourceSet(const JsonNode & node) { for(auto i = 0; i < GameConstants::RESOURCE_QUANTITY; i++) container[i] = static_cast(node[GameConstants::RESOURCE_NAMES[i]].Float()); } -Res::ResourceSet::ResourceSet(TResource wood, TResource mercury, TResource ore, TResource sulfur, TResource crystal, +ResourceSet::ResourceSet(TResource wood, TResource mercury, TResource ore, TResource sulfur, TResource crystal, TResource gems, TResource gold, TResource mithril) { - container[Res::WOOD] = wood; - container[Res::MERCURY] = mercury; - container[Res::ORE] = ore; - container[Res::SULFUR] = sulfur; - container[Res::CRYSTAL] = crystal; - container[Res::GEMS] = gems; - container[Res::GOLD] = gold; - container[Res::MITHRIL] = mithril; + container[GameResID(EGameResID::WOOD)] = wood; + container[GameResID(EGameResID::MERCURY)] = mercury; + container[GameResID(EGameResID::ORE)] = ore; + container[GameResID(EGameResID::SULFUR)] = sulfur; + container[GameResID(EGameResID::CRYSTAL)] = crystal; + container[GameResID(EGameResID::GEMS)] = gems; + container[GameResID(EGameResID::GOLD)] = gold; + container[GameResID(EGameResID::MITHRIL)] = mithril; } -void Res::ResourceSet::serializeJson(JsonSerializeFormat & handler, const std::string & fieldName) +void ResourceSet::serializeJson(JsonSerializeFormat & handler, const std::string & fieldName) { if(handler.saving && !nonZero()) return; @@ -49,7 +49,7 @@ void Res::ResourceSet::serializeJson(JsonSerializeFormat & handler, const std::s handler.serializeInt(GameConstants::RESOURCE_NAMES[idx], this->operator[](idx), 0); } -bool Res::ResourceSet::nonZero() const +bool ResourceSet::nonZero() const { for(const auto & elem : *this) if(elem) @@ -58,35 +58,25 @@ bool Res::ResourceSet::nonZero() const return false; } -void Res::ResourceSet::amax(const TResourceCap &val) +void ResourceSet::amax(const TResourceCap &val) { for(auto & elem : *this) vstd::amax(elem, val); } -void Res::ResourceSet::amin(const TResourceCap &val) +void ResourceSet::amin(const TResourceCap &val) { for(auto & elem : *this) vstd::amin(elem, val); } -void Res::ResourceSet::positive() +void ResourceSet::positive() { for(auto & elem : *this) vstd::amax(elem, 0); } -bool Res::ResourceSet::canBeAfforded(const ResourceSet &res) const -{ - return Res::canAfford(res, *this); -} - -bool Res::ResourceSet::canAfford(const ResourceSet &price) const -{ - return Res::canAfford(*this, price); -} - -bool Res::canAfford(const ResourceSet &res, const ResourceSet &price) +static bool canAfford(const ResourceSet &res, const ResourceSet &price) { assert(res.size() == price.size() && price.size() == GameConstants::RESOURCE_QUANTITY); for(int i = 0; i < GameConstants::RESOURCE_QUANTITY; i++) @@ -96,7 +86,17 @@ bool Res::canAfford(const ResourceSet &res, const ResourceSet &price) return true; } -TResourceCap Res::ResourceSet::marketValue() const +bool ResourceSet::canBeAfforded(const ResourceSet &res) const +{ + return VCMI_LIB_WRAP_NAMESPACE(canAfford(res, *this)); +} + +bool ResourceSet::canAfford(const ResourceSet &price) const +{ + return VCMI_LIB_WRAP_NAMESPACE(canAfford(*this, price)); +} + +TResourceCap ResourceSet::marketValue() const { TResourceCap total = 0; for(int i = 0; i < GameConstants::RESOURCE_QUANTITY; i++) @@ -104,7 +104,7 @@ TResourceCap Res::ResourceSet::marketValue() const return total; } -std::string Res::ResourceSet::toString() const +std::string ResourceSet::toString() const { std::ostringstream out; out << "["; @@ -117,35 +117,35 @@ std::string Res::ResourceSet::toString() const return out.str(); } -bool Res::ResourceSet::nziterator::valid() const +bool ResourceSet::nziterator::valid() const { return cur.resType < GameConstants::RESOURCE_QUANTITY && cur.resVal; } -Res::ResourceSet::nziterator Res::ResourceSet::nziterator::operator++() +ResourceSet::nziterator ResourceSet::nziterator::operator++() { advance(); return *this; } -Res::ResourceSet::nziterator Res::ResourceSet::nziterator::operator++(int) +ResourceSet::nziterator ResourceSet::nziterator::operator++(int) { nziterator ret = *this; advance(); return ret; } -const Res::ResourceSet::nziterator::ResEntry& Res::ResourceSet::nziterator::operator*() const +const ResourceSet::nziterator::ResEntry& ResourceSet::nziterator::operator*() const { return cur; } -const Res::ResourceSet::nziterator::ResEntry * Res::ResourceSet::nziterator::operator->() const +const ResourceSet::nziterator::ResEntry * ResourceSet::nziterator::operator->() const { return &cur; } -void Res::ResourceSet::nziterator::advance() +void ResourceSet::nziterator::advance() { do { @@ -156,11 +156,11 @@ void Res::ResourceSet::nziterator::advance() cur.resVal = -1; } -Res::ResourceSet::nziterator::nziterator(const ResourceSet &RS) +ResourceSet::nziterator::nziterator(const ResourceSet &RS) : rs(RS) { - cur.resType = WOOD; - cur.resVal = rs[WOOD]; + cur.resType = EGameResID::WOOD; + cur.resVal = rs[EGameResID::WOOD]; if(!valid()) advance(); diff --git a/lib/ResourceSet.h b/lib/ResourceSet.h index b551765e2..611b24e8d 100644 --- a/lib/ResourceSet.h +++ b/lib/ResourceSet.h @@ -11,6 +11,7 @@ #pragma once #include "GameConstants.h" + VCMI_LIB_NAMESPACE_BEGIN using TResource = int32_t; @@ -19,169 +20,168 @@ using TResourceCap = int64_t; //to avoid overflow when adding integers. Signed v class JsonNode; class JsonSerializeFormat; -namespace Res +class ResourceSet; + +enum class EGameResID : int8_t { - class ResourceSet; - bool canAfford(const ResourceSet &res, const ResourceSet &price); //can a be used to pay price b + WOOD = 0, MERCURY, ORE, SULFUR, CRYSTAL, GEMS, GOLD, MITHRIL, - enum ERes - { - WOOD = 0, MERCURY, ORE, SULFUR, CRYSTAL, GEMS, GOLD, MITHRIL, + WOOD_AND_ORE = 127, // special case for town bonus resource + INVALID = -1 +}; - WOOD_AND_ORE = 127, // special case for town bonus resource - INVALID = -1 - }; +using GameResID = Identifier; - //class to be representing a vector of resource - class ResourceSet - { - private: - std::array container; - public: - // read resources set from json. Format example: { "gold": 500, "wood":5 } - DLL_LINKAGE ResourceSet(const JsonNode & node); - DLL_LINKAGE ResourceSet(TResource wood = 0, TResource mercury = 0, TResource ore = 0, TResource sulfur = 0, TResource crystal = 0, - TResource gems = 0, TResource gold = 0, TResource mithril = 0); +//class to be representing a vector of resource +class ResourceSet +{ +private: + std::array container; +public: + // read resources set from json. Format example: { "gold": 500, "wood":5 } + DLL_LINKAGE ResourceSet(const JsonNode & node); + DLL_LINKAGE ResourceSet(TResource wood = 0, TResource mercury = 0, TResource ore = 0, TResource sulfur = 0, TResource crystal = 0, + TResource gems = 0, TResource gold = 0, TResource mithril = 0); #define scalarOperator(OPSIGN) \ - ResourceSet& operator OPSIGN ## =(const TResource &rhs) \ - { \ - for(auto i = 0; i < container.size(); i++) \ - container.at(i) OPSIGN ## = rhs; \ - \ - return *this; \ - } + ResourceSet& operator OPSIGN ## =(const TResource &rhs) \ + { \ + for(auto i = 0; i < container.size(); i++) \ + container.at(i) OPSIGN ## = rhs; \ + \ + return *this; \ + } #define vectorOperator(OPSIGN) \ - ResourceSet& operator OPSIGN ## =(const ResourceSet &rhs) \ - { \ - for(auto i = 0; i < container.size(); i++) \ - container.at(i) OPSIGN ## = rhs[i]; \ - \ - return *this; \ - } + ResourceSet& operator OPSIGN ## =(const ResourceSet &rhs) \ + { \ + for(auto i = 0; i < container.size(); i++) \ + container.at(i) OPSIGN ## = rhs[i]; \ + \ + return *this; \ + } #define twoOperands(OPSIGN, RHS_TYPE) \ - friend ResourceSet operator OPSIGN(ResourceSet lhs, const RHS_TYPE &rhs) \ - { \ - lhs OPSIGN ## = rhs; \ - return lhs; \ - } + friend ResourceSet operator OPSIGN(ResourceSet lhs, const RHS_TYPE &rhs) \ + { \ + lhs OPSIGN ## = rhs; \ + return lhs; \ + } - scalarOperator(+) - scalarOperator(-) - scalarOperator(*) - scalarOperator(/) - vectorOperator(+) - vectorOperator(-) - twoOperands(+, TResource) - twoOperands(-, TResource) - twoOperands(*, TResource) - twoOperands(/, TResource) - twoOperands(+, ResourceSet) - twoOperands(-, ResourceSet) + scalarOperator(+) + scalarOperator(-) + scalarOperator(*) + scalarOperator(/) + vectorOperator(+) + vectorOperator(-) + twoOperands(+, TResource) + twoOperands(-, TResource) + twoOperands(*, TResource) + twoOperands(/, TResource) + twoOperands(+, ResourceSet) + twoOperands(-, ResourceSet) #undef scalarOperator #undef vectorOperator #undef twoOperands - using const_reference = decltype(container)::const_reference; - using value_type = decltype(container)::value_type; - using const_iterator = decltype(container)::const_iterator; - using iterator = decltype(container)::iterator; + using const_reference = decltype(container)::const_reference; + using value_type = decltype(container)::value_type; + using const_iterator = decltype(container)::const_iterator; + using iterator = decltype(container)::iterator; - // Array-like interface - TResource & operator[](Res::ERes index) - { - return operator[](static_cast(index)); - } + // Array-like interface + TResource & operator[](GameResID index) + { + return operator[](index.getNum()); + } - const TResource & operator[](Res::ERes index) const - { - return operator[](static_cast(index)); - } + const TResource & operator[](GameResID index) const + { + return operator[](index.getNum()); + } - TResource & operator[](size_t index) - { - return container.at(index); - } + TResource & operator[](size_t index) + { + return container.at(index); + } - const TResource & operator[](size_t index) const - { - return container.at(index); - } + const TResource & operator[](size_t index) const + { + return container.at(index); + } - bool empty () const - { - for(const auto & res : *this) - if(res) - return false; + bool empty () const + { + for(const auto & res : *this) + if(res) + return false; - return true; - } + return true; + } - // C++ range-based for support - auto begin () -> decltype (container.begin()) - { - return container.begin(); - } + // C++ range-based for support + auto begin () -> decltype (container.begin()) + { + return container.begin(); + } - auto end () -> decltype (container.end()) - { - return container.end(); - } + auto end () -> decltype (container.end()) + { + return container.end(); + } - auto begin () const -> decltype (container.cbegin()) - { - return container.cbegin(); - } + auto begin () const -> decltype (container.cbegin()) + { + return container.cbegin(); + } - auto end () const -> decltype (container.cend()) - { - return container.cend(); - } + auto end () const -> decltype (container.cend()) + { + return container.cend(); + } - auto size () const -> decltype (container.size()) - { - return container.size(); - } + auto size () const -> decltype (container.size()) + { + return container.size(); + } - //to be used for calculations of type "how many units of sth can I afford?" - int operator/(const ResourceSet &rhs) - { - int ret = INT_MAX; - for(int i = 0; i < container.size(); i++) - if(rhs[i]) - vstd::amin(ret, container.at(i) / rhs[i]); + //to be used for calculations of type "how many units of sth can I afford?" + int operator/(const ResourceSet &rhs) + { + int ret = INT_MAX; + for(int i = 0; i < container.size(); i++) + if(rhs[i]) + vstd::amin(ret, container.at(i) / rhs[i]); - return ret; - } + return ret; + } - ResourceSet & operator=(const TResource &rhs) - { - for(int i = 0; i < container.size(); i++) - container.at(i) = rhs; + ResourceSet & operator=(const TResource &rhs) + { + for(int i = 0; i < container.size(); i++) + container.at(i) = rhs; - return *this; - } + return *this; + } - ResourceSet operator-() const - { - ResourceSet ret; - for(int i = 0; i < container.size(); i++) - ret[i] = -container.at(i); - return ret; - } + ResourceSet operator-() const + { + ResourceSet ret; + for(int i = 0; i < container.size(); i++) + ret[i] = -container.at(i); + return ret; + } - bool operator==(const ResourceSet &rhs) const - { - return this->container == rhs.container; - } + bool operator==(const ResourceSet &rhs) const + { + return this->container == rhs.container; + } - // WARNING: comparison operators are used for "can afford" relation: a <= b means that foreach i a[i] <= b[i] - // that doesn't work the other way: a > b doesn't mean that a cannot be afforded with b, it's still b can afford a +// WARNING: comparison operators are used for "can afford" relation: a <= b means that foreach i a[i] <= b[i] +// that doesn't work the other way: a > b doesn't mean that a cannot be afforded with b, it's still b can afford a // bool operator<(const ResourceSet &rhs) // { // for(int i = 0; i < size(); i++) @@ -191,49 +191,47 @@ namespace Res // return true; // } - template void serialize(Handler &h, const int version) + template void serialize(Handler &h, const int version) + { + h & container; + } + + DLL_LINKAGE void serializeJson(JsonSerializeFormat & handler, const std::string & fieldName); + + DLL_LINKAGE void amax(const TResourceCap &val); //performs vstd::amax on each element + DLL_LINKAGE void amin(const TResourceCap &val); //performs vstd::amin on each element + DLL_LINKAGE void positive(); //values below 0 are set to 0 - upgrade cost can't be negative, for example + DLL_LINKAGE bool nonZero() const; //returns true if at least one value is non-zero; + DLL_LINKAGE bool canAfford(const ResourceSet &price) const; + DLL_LINKAGE bool canBeAfforded(const ResourceSet &res) const; + DLL_LINKAGE TResourceCap marketValue() const; + + DLL_LINKAGE std::string toString() const; + + //special iterator of iterating over non-zero resources in set + class DLL_LINKAGE nziterator + { + struct ResEntry { - h & container; - } - - DLL_LINKAGE void serializeJson(JsonSerializeFormat & handler, const std::string & fieldName); - - DLL_LINKAGE void amax(const TResourceCap &val); //performs vstd::amax on each element - DLL_LINKAGE void amin(const TResourceCap &val); //performs vstd::amin on each element - DLL_LINKAGE void positive(); //values below 0 are set to 0 - upgrade cost can't be negative, for example - DLL_LINKAGE bool nonZero() const; //returns true if at least one value is non-zero; - DLL_LINKAGE bool canAfford(const ResourceSet &price) const; - DLL_LINKAGE bool canBeAfforded(const ResourceSet &res) const; - DLL_LINKAGE TResourceCap marketValue() const; - - DLL_LINKAGE std::string toString() const; - - //special iterator of iterating over non-zero resources in set - class DLL_LINKAGE nziterator - { - struct ResEntry - { - Res::ERes resType; - TResourceCap resVal; - } cur; - const ResourceSet &rs; - void advance(); - - public: - nziterator(const ResourceSet &RS); - bool valid() const; - nziterator operator++(); - nziterator operator++(int); - const ResEntry& operator*() const; - const ResEntry* operator->() const; - - }; - + GameResID resType; + TResourceCap resVal; + } cur; + const ResourceSet &rs; + void advance(); + public: + nziterator(const ResourceSet &RS); + bool valid() const; + nziterator operator++(); + nziterator operator++(int); + const ResEntry& operator*() const; + const ResEntry* operator->() const; }; -} -using TResources = Res::ResourceSet; + +}; + +using TResources = ResourceSet; VCMI_LIB_NAMESPACE_END diff --git a/lib/battle/BattleInfo.cpp b/lib/battle/BattleInfo.cpp index 84b1e93e4..c9ebd8b04 100644 --- a/lib/battle/BattleInfo.cpp +++ b/lib/battle/BattleInfo.cpp @@ -653,7 +653,7 @@ int32_t BattleInfo::getEnchanterCounter(ui8 side) const return sides.at(side).enchanterCounter; } -const IBonusBearer * BattleInfo::asBearer() const +const IBonusBearer * BattleInfo::getBonusBearer() const { return this; } diff --git a/lib/battle/BattleInfo.h b/lib/battle/BattleInfo.h index e70f2e413..d6d4d30f0 100644 --- a/lib/battle/BattleInfo.h +++ b/lib/battle/BattleInfo.h @@ -93,7 +93,7 @@ public: uint32_t getCastSpells(ui8 side) const override; int32_t getEnchanterCounter(ui8 side) const override; - const IBonusBearer * asBearer() const override; + const IBonusBearer * getBonusBearer() const override; uint32_t nextUnitId() const override; diff --git a/lib/battle/BattleProxy.cpp b/lib/battle/BattleProxy.cpp index 0209f0d10..f62a5a073 100644 --- a/lib/battle/BattleProxy.cpp +++ b/lib/battle/BattleProxy.cpp @@ -108,9 +108,9 @@ int32_t BattleProxy::getEnchanterCounter(ui8 side) const return subject->battleGetEnchanterCounter(side); } -const IBonusBearer * BattleProxy::asBearer() const +const IBonusBearer * BattleProxy::getBonusBearer() const { - return subject->getBattleNode(); + return subject->getBonusBearer(); } diff --git a/lib/battle/BattleProxy.h b/lib/battle/BattleProxy.h index 0e07e707c..da0880528 100644 --- a/lib/battle/BattleProxy.h +++ b/lib/battle/BattleProxy.h @@ -50,7 +50,7 @@ public: uint32_t getCastSpells(ui8 side) const override; int32_t getEnchanterCounter(ui8 side) const override; - const IBonusBearer * asBearer() const override; + const IBonusBearer * getBonusBearer() const override; protected: Subject subject; }; diff --git a/lib/battle/BattleStateInfoForRetreat.cpp b/lib/battle/BattleStateInfoForRetreat.cpp index 676c0cc12..8eabecc12 100644 --- a/lib/battle/BattleStateInfoForRetreat.cpp +++ b/lib/battle/BattleStateInfoForRetreat.cpp @@ -33,7 +33,7 @@ uint64_t getFightingStrength(const std::vector & stacks, c for(const battle::Unit * stack : stacks) { - result += stack->creatureId().toCreature()->AIValue * stack->getCount(); + result += stack->creatureId().toCreature()->getAIValue() * stack->getCount(); } if(hero) diff --git a/lib/battle/CBattleInfoCallback.cpp b/lib/battle/CBattleInfoCallback.cpp index 170a523a4..c9b205102 100644 --- a/lib/battle/CBattleInfoCallback.cpp +++ b/lib/battle/CBattleInfoCallback.cpp @@ -1721,7 +1721,7 @@ si8 CBattleInfoCallback::battleMinSpellLevel(ui8 side) const if(const CGHeroInstance * h = battleGetFightingHero(side)) node = h; else - node = getBattleNode(); + node = getBonusBearer(); if(!node) return 0; @@ -1739,7 +1739,7 @@ si8 CBattleInfoCallback::battleMaxSpellLevel(ui8 side) const if(const CGHeroInstance * h = battleGetFightingHero(side)) node = h; else - node = getBattleNode(); + node = getBonusBearer(); if(!node) return GameConstants::SPELL_LEVELS; diff --git a/lib/battle/CBattleInfoEssentials.cpp b/lib/battle/CBattleInfoEssentials.cpp index ac3929ea3..5eb15921e 100644 --- a/lib/battle/CBattleInfoEssentials.cpp +++ b/lib/battle/CBattleInfoEssentials.cpp @@ -252,9 +252,9 @@ uint32_t CBattleInfoEssentials::battleCastSpells(ui8 side) const return getBattle()->getCastSpells(side); } -const IBonusBearer * CBattleInfoEssentials::getBattleNode() const +const IBonusBearer * CBattleInfoEssentials::getBonusBearer() const { - return getBattle()->asBearer(); + return getBattle()->getBonusBearer(); } bool CBattleInfoEssentials::battleCanFlee(const PlayerColor & player) const diff --git a/lib/battle/CBattleInfoEssentials.h b/lib/battle/CBattleInfoEssentials.h index ca0b0b93f..816735eda 100644 --- a/lib/battle/CBattleInfoEssentials.h +++ b/lib/battle/CBattleInfoEssentials.h @@ -46,7 +46,7 @@ public: }; BattlePerspective::BattlePerspective battleGetMySide() const; - const IBonusBearer * getBattleNode() const; + const IBonusBearer * getBonusBearer() const override; TerrainId battleTerrainType() const override; BattleField battleGetBattlefieldType() const override; diff --git a/lib/battle/CUnitState.cpp b/lib/battle/CUnitState.cpp index fdb17a179..6d9411ac2 100644 --- a/lib/battle/CUnitState.cpp +++ b/lib/battle/CUnitState.cpp @@ -395,22 +395,22 @@ CreatureID CUnitState::creatureId() const int32_t CUnitState::creatureLevel() const { - return static_cast(unitType()->level); + return static_cast(unitType()->getLevel()); } bool CUnitState::doubleWide() const { - return unitType()->doubleWide; + return unitType()->isDoubleWide(); } int32_t CUnitState::creatureCost() const { - return unitType()->cost[Res::GOLD]; + return unitType()->getRecruitCost(EGameResID::GOLD); } int32_t CUnitState::creatureIconIndex() const { - return unitType()->iconIndex; + return unitType()->getIconIndex(); } int32_t CUnitState::getCasterUnitId() const diff --git a/lib/battle/DamageCalculator.cpp b/lib/battle/DamageCalculator.cpp index 80d31bf48..c3b89f480 100644 --- a/lib/battle/DamageCalculator.cpp +++ b/lib/battle/DamageCalculator.cpp @@ -145,7 +145,7 @@ int DamageCalculator::getActorAttackSlayer() const int attackBonus = SpellID(SpellID::SLAYER).toSpell()->getLevelPower(spLevel); if(info.attacker->hasBonusOfType(Bonus::SPECIAL_PECULIAR_ENCHANT, SpellID::SLAYER)) { - ui8 attackerTier = info.attacker->unitType()->level; + ui8 attackerTier = info.attacker->unitType()->getLevel(); ui8 specialtyBonus = std::max(5 - attackerTier, 0); attackBonus += specialtyBonus; } diff --git a/lib/battle/IBattleInfoCallback.h b/lib/battle/IBattleInfoCallback.h index 223986eef..8c0a6fa2f 100644 --- a/lib/battle/IBattleInfoCallback.h +++ b/lib/battle/IBattleInfoCallback.h @@ -13,6 +13,8 @@ #include "GameConstants.h" #include "BattleHex.h" +#include + VCMI_LIB_NAMESPACE_BEGIN struct CObstacleInstance; @@ -45,7 +47,7 @@ namespace scripting } #endif -class DLL_LINKAGE IBattleInfoCallback +class DLL_LINKAGE IBattleInfoCallback : public WithBonuses { public: #if SCRIPTING_ENABLED diff --git a/lib/battle/IBattleState.h b/lib/battle/IBattleState.h index ab98a6d89..2f635a4d1 100644 --- a/lib/battle/IBattleState.h +++ b/lib/battle/IBattleState.h @@ -30,7 +30,7 @@ namespace battle class UnitInfo; } -class DLL_LINKAGE IBattleInfo +class DLL_LINKAGE IBattleInfo : public WithBonuses { public: using ObstacleCList = std::vector>; @@ -62,8 +62,6 @@ public: virtual ui8 getTacticDist() const = 0; virtual ui8 getTacticsSide() const = 0; - virtual const IBonusBearer * asBearer() const = 0; - virtual uint32_t nextUnitId() const = 0; virtual int64_t getActualDamage(const DamageRange & damage, int32_t attackerCount, vstd::RNG & rng) const = 0; diff --git a/lib/mapObjects/CArmedInstance.cpp b/lib/mapObjects/CArmedInstance.cpp index a44ef938f..4700b9d5c 100644 --- a/lib/mapObjects/CArmedInstance.cpp +++ b/lib/mapObjects/CArmedInstance.cpp @@ -76,7 +76,7 @@ void CArmedInstance::updateMoraleBonusFromArmy() const CStackInstance * inst = slot.second; const CCreature * creature = VLC->creh->objects[inst->getCreatureID()]; - factions.insert(creature->faction); + factions.insert(creature->getFactionIndex()); // Check for undead flag instead of faction (undead mummies are neutral) if (!hasUndead) { diff --git a/lib/mapObjects/CBank.cpp b/lib/mapObjects/CBank.cpp index cfdbacd7d..a1e58bf5c 100644 --- a/lib/mapObjects/CBank.cpp +++ b/lib/mapObjects/CBank.cpp @@ -229,7 +229,7 @@ void CBank::doVisit(const CGHeroInstance * hero) const loot << "%d %s"; loot.addReplacement(iw.components.back().val); loot.addReplacement(MetaString::RES_NAMES, iw.components.back().subtype); - cb->giveResource(hero->getOwner(), static_cast(it), bc->resources[it]); + cb->giveResource(hero->getOwner(), static_cast(it), bc->resources[it]); } } //grant artifacts @@ -246,9 +246,9 @@ void CBank::doVisit(const CGHeroInstance * hero) const iw.text.addTxt(MetaString::ADVOB_TXT, textID); if (textID == 34) { - const CCreature * strongest = boost::range::max_element(bc->guards, [](const CStackBasicDescriptor & a, const CStackBasicDescriptor & b) + const auto * strongest = boost::range::max_element(bc->guards, [](const CStackBasicDescriptor & a, const CStackBasicDescriptor & b) { - return a.type->fightValue < b.type->fightValue; + return a.type->getFightValue() < b.type->getFightValue(); })->type; iw.text.addReplacement(MetaString::CRE_PL_NAMES, strongest->getId()); @@ -305,7 +305,7 @@ void CBank::doVisit(const CGHeroInstance * hero) const CCreatureSet ourArmy; for(const auto & slot : bc->creatures) { - ourArmy.addToSlot(ourArmy.getSlotFor(slot.type->idNumber), slot.type->getId(), slot.count); + ourArmy.addToSlot(ourArmy.getSlotFor(slot.type->getId()), slot.type->getId(), slot.count); } for(const auto & elem : ourArmy.Slots()) diff --git a/lib/mapObjects/CGHeroInstance.cpp b/lib/mapObjects/CGHeroInstance.cpp index 2943706b0..126521780 100644 --- a/lib/mapObjects/CGHeroInstance.cpp +++ b/lib/mapObjects/CGHeroInstance.cpp @@ -325,7 +325,7 @@ void CGHeroInstance::initHero(CRandomGenerator & rand) if (VLC->settings()->getBoolean(EGameSettings::MODULE_COMMANDERS) && !commander) { - commander = new CCommanderInstance(type->heroClass->commander->idNumber); + commander = new CCommanderInstance(type->heroClass->commander->getId()); commander->setArmyObj (castToArmyObj()); //TODO: separate function for setting commanders commander->giveStackExp (exp); //after our exp is set } @@ -790,7 +790,7 @@ CStackBasicDescriptor CGHeroInstance::calculateNecromancy (const BattleResult &b }; int maxCasualtyLevel = 1; for(const auto & casualty : casualties) - vstd::amax(maxCasualtyLevel, VLC->creh->objects[casualty.first]->level); + vstd::amax(maxCasualtyLevel, VLC->creatures()->getByIndex(casualty.first)->getLevel()); // pick best bonus available std::shared_ptr topPick; for(const std::shared_ptr & newPick : *improvedNecromancy) @@ -806,8 +806,8 @@ CStackBasicDescriptor CGHeroInstance::calculateNecromancy (const BattleResult &b { auto quality = [getCreatureID](const std::shared_ptr & pick) -> std::tuple { - const CCreature * c = VLC->creh->objects[getCreatureID(pick)]; - return std::tuple {c->level, static_cast(c->cost.marketValue()), -pick->additionalInfo[1]}; + const auto * c = getCreatureID(pick).toCreature(); + return std::tuple {c->getLevel(), static_cast(c->getFullRecruitCost().marketValue()), -pick->additionalInfo[1]}; }; if(quality(topPick) < quality(newPick)) topPick = newPick; @@ -840,7 +840,7 @@ CStackBasicDescriptor CGHeroInstance::calculateNecromancy (const BattleResult &b { const CCreature * c = VLC->creh->objects[casualty.first]; double raisedFromCasualty = std::min(c->MaxHealth() / raisedUnitHealth, 1.0) * casualty.second * necromancySkill; - if(c->level < requiredCasualtyLevel) + if(c->getLevel() < requiredCasualtyLevel) raisedFromCasualty *= 0.5; raisedUnits += raisedFromCasualty; } diff --git a/lib/mapObjects/CGMarket.cpp b/lib/mapObjects/CGMarket.cpp index 762088784..6ba1ee577 100644 --- a/lib/mapObjects/CGMarket.cpp +++ b/lib/mapObjects/CGMarket.cpp @@ -50,7 +50,7 @@ bool IMarket::getOffer(int id1, int id2, int &val1, int &val2, EMarketMode::EMar const double effectivenessArray[] = {0.0, 0.3, 0.45, 0.50, 0.65, 0.7, 0.85, 0.9, 1.0}; double effectiveness = effectivenessArray[std::min(getMarketEfficiency(), 8)]; - double r = VLC->creh->objects[id1]->cost[6]; //value of given creature in gold + double r = VLC->creatures()->getByIndex(id1)->getRecruitCost(EGameResID::GOLD); //value of given creature in gold double g = VLC->objh->resVals[id2] / effectiveness; //value of wanted resource if(r>g) //if given resource is more expensive than wanted @@ -98,7 +98,7 @@ bool IMarket::getOffer(int id1, int id2, int &val1, int &val2, EMarketMode::EMar case EMarketMode::CREATURE_EXP: { val1 = 1; - val2 = (VLC->creh->objects[id1]->AIValue / 40) * 5; + val2 = (VLC->creh->objects[id1]->getAIValue() / 40) * 5; } break; case EMarketMode::ARTIFACT_EXP: diff --git a/lib/mapObjects/CGTownInstance.cpp b/lib/mapObjects/CGTownInstance.cpp index a41e8d1e7..c1c70b782 100644 --- a/lib/mapObjects/CGTownInstance.cpp +++ b/lib/mapObjects/CGTownInstance.cpp @@ -263,7 +263,7 @@ void CGDwelling::newTurn(CRandomGenerator & rand) const creaturesAccumulate = VLC->settings()->getBoolean(EGameSettings::DWELLINGS_ACCUMULATE_WHEN_NEUTRAL); CCreature *cre = VLC->creh->objects[creatures[i].second[0]]; - TQuantity amount = cre->growth * (1 + cre->valOfBonuses(Bonus::CREATURE_GROWTH_PERCENT)/100) + cre->valOfBonuses(Bonus::CREATURE_GROWTH); + TQuantity amount = cre->getGrowth() * (1 + cre->valOfBonuses(Bonus::CREATURE_GROWTH_PERCENT)/100) + cre->valOfBonuses(Bonus::CREATURE_GROWTH); if (creaturesAccumulate && ID != Obj::REFUGEE_CAMP) //camp should not try to accumulate different kinds of creatures sac.creatures[i].first += amount; else @@ -287,7 +287,7 @@ void CGDwelling::updateGuards() const //default condition - creatures are of level 5 or higher for (auto creatureEntry : creatures) { - if (VLC->creh->objects[creatureEntry.second.at(0)]->level >= 5 && ID != Obj::REFUGEE_CAMP) + if (VLC->creatures()->getByIndex(creatureEntry.second.at(0))->getLevel() >= 5 && ID != Obj::REFUGEE_CAMP) { guarded = true; break; @@ -299,14 +299,14 @@ void CGDwelling::updateGuards() const for (auto creatureEntry : creatures) { const CCreature * crea = VLC->creh->objects[creatureEntry.second.at(0)]; - SlotID slot = getSlotFor(crea->idNumber); + SlotID slot = getSlotFor(crea->getId()); if (hasStackAtSlot(slot)) //stack already exists, overwrite it { ChangeStackCount csc; csc.army = this->id; csc.slot = slot; - csc.count = crea->growth * 3; + csc.count = crea->getGrowth() * 3; csc.absoluteValue = true; cb->sendAndApply(&csc); } @@ -315,8 +315,8 @@ void CGDwelling::updateGuards() const InsertNewStack ns; ns.army = this->id; ns.slot = slot; - ns.type = crea->idNumber; - ns.count = crea->growth * 3; + ns.type = crea->getId(); + ns.count = crea->getGrowth() * 3; cb->sendAndApply(&ns); } } @@ -326,10 +326,10 @@ void CGDwelling::updateGuards() const void CGDwelling::heroAcceptsCreatures( const CGHeroInstance *h) const { CreatureID crid = creatures[0].second[0]; - CCreature *crs = VLC->creh->objects[crid]; + auto *crs = crid.toCreature(); TQuantity count = creatures[0].first; - if(crs->level == 1 && ID != Obj::REFUGEE_CAMP) //first level - creatures are for free + if(crs->getLevel() == 1 && ID != Obj::REFUGEE_CAMP) //first level - creatures are for free { if(count) //there are available creatures { @@ -538,7 +538,7 @@ GrowthInfo CGTownInstance::getGrowthInfo(int level) const return ret; //no dwelling const CCreature *creature = VLC->creh->objects[creatures[level].second.back()]; - const int base = creature->growth; + const int base = creature->getGrowth(); int castleBonus = 0; ret.entries.emplace_back(VLC->generaltexth->allTexts[590], base); // \n\nBasic growth %d" @@ -550,11 +550,11 @@ GrowthInfo CGTownInstance::getGrowthInfo(int level) const if(town->hordeLvl.at(0) == level)//horde 1 if(hasBuilt(BuildingID::HORDE_1)) - ret.entries.emplace_back(subID, BuildingID::HORDE_1, creature->hordeGrowth); + ret.entries.emplace_back(subID, BuildingID::HORDE_1, creature->getHorde()); if(town->hordeLvl.at(1) == level)//horde 2 if(hasBuilt(BuildingID::HORDE_2)) - ret.entries.emplace_back(subID, BuildingID::HORDE_2, creature->hordeGrowth); + ret.entries.emplace_back(subID, BuildingID::HORDE_2, creature->getHorde()); //statue-of-legion-like bonus: % to base+castle TConstBonusListPtr bonuses2 = getBonuses(Selector::type()(Bonus::CREATURE_GROWTH_PERCENT)); @@ -915,7 +915,7 @@ void CGTownInstance::newTurn(CRandomGenerator & rand) const int resID = rand.nextInt(2, 5); //bonus to random rare resource resID = (resID==2)?1:resID; int resVal = rand.nextInt(1, 4);//with size 1..4 - cb->giveResource(tempOwner, static_cast(resID), resVal); + cb->giveResource(tempOwner, static_cast(resID), resVal); cb->setObjProperty (id, ObjProperty::BONUS_VALUE_FIRST, resID); cb->setObjProperty (id, ObjProperty::BONUS_VALUE_SECOND, resVal); } @@ -938,7 +938,7 @@ void CGTownInstance::newTurn(CRandomGenerator & rand) const std::vector nativeCrits; //slots for(const auto & elem : Slots()) { - if (elem.second->type->faction == subID) //native + if (elem.second->type->getFactionIndex() == subID) //native { nativeCrits.push_back(elem.first); //collect matching slots } @@ -951,7 +951,7 @@ void CGTownInstance::newTurn(CRandomGenerator & rand) const const CCreature *c = getCreature(pos); if (rand.nextInt(99) < 90 || c->upgrades.empty()) //increase number if no upgrade available { - cb->changeStackCount(sl, c->growth); + cb->changeStackCount(sl, c->getGrowth()); } else //upgrade { @@ -968,7 +968,7 @@ void CGTownInstance::newTurn(CRandomGenerator & rand) const TQuantity count = creatureGrowth(i); if (!count) // no dwelling - count = VLC->creh->objects[c]->growth; + count = VLC->creh->objects[c]->getGrowth(); {//no lower tiers or above current month diff --git a/lib/mapObjects/CObjectHandler.cpp b/lib/mapObjects/CObjectHandler.cpp index 95e53c6d1..5e03700fd 100644 --- a/lib/mapObjects/CObjectHandler.cpp +++ b/lib/mapObjects/CObjectHandler.cpp @@ -494,8 +494,8 @@ void IBoatGenerator::getProblemText(MetaString &out, const CGHeroInstance *visit void IShipyard::getBoatCost(TResources & cost) const { - cost[Res::WOOD] = 10; - cost[Res::GOLD] = 1000; + cost[EGameResID::WOOD] = 10; + cost[EGameResID::GOLD] = 1000; } IShipyard::IShipyard(const CGObjectInstance *O) diff --git a/lib/mapObjects/CQuest.cpp b/lib/mapObjects/CQuest.cpp index b7e54284e..bf74e24ab 100644 --- a/lib/mapObjects/CQuest.cpp +++ b/lib/mapObjects/CQuest.cpp @@ -163,7 +163,7 @@ bool CQuest::checkQuest(const CGHeroInstance * h) const case MISSION_ARMY: return checkMissionArmy(this, h); case MISSION_RESOURCES: - for(Res::ERes i = Res::WOOD; i <= Res::GOLD; vstd::advance(i, +1)) //including Mithril ? + for(auto i = EGameResID::WOOD; i <= EGameResID::GOLD; vstd::advance(i, +1)) //including Mithril ? { //Quest has no direct access to callback if(CGHeroInstance::cb->getResource(h->tempOwner, i) < static_cast(m7resources[i])) return false; @@ -821,7 +821,7 @@ void CGSeerHut::finishQuest(const CGHeroInstance * h, ui32 accept) const case CQuest::MISSION_RESOURCES: for (int i = 0; i < 7; ++i) { - cb->giveResource(h->getOwner(), static_cast(i), -static_cast(quest->m7resources[i])); + cb->giveResource(h->getOwner(), static_cast(i), -static_cast(quest->m7resources[i])); } break; default: @@ -858,7 +858,7 @@ void CGSeerHut::completeQuest (const CGHeroInstance * h) const //reward } break; case RESOURCES: - cb->giveResource(h->getOwner(), static_cast(rID), rVal); + cb->giveResource(h->getOwner(), static_cast(rID), rVal); break; case PRIMARY_SKILL: cb->changePrimSkill(h, static_cast(rID), rVal, false); diff --git a/lib/mapObjects/CQuest.h b/lib/mapObjects/CQuest.h index a236cf997..a6f414fa5 100644 --- a/lib/mapObjects/CQuest.h +++ b/lib/mapObjects/CQuest.h @@ -12,6 +12,7 @@ #include "CObjectHandler.h" #include "CArmedInstance.h" +#include "../ResourceSet.h" #include "../CCreatureSet.h" #include "../NetPacksBase.h" @@ -58,7 +59,7 @@ public: std::vector m2stats; std::vector m5arts; // artifact IDs. Add IDs through addArtifactID(), not directly to the field. std::vector m6creatures; //pair[cre id, cre count], CreatureSet info irrelevant - std::vector m7resources; //TODO: use resourceset? + TResources m7resources; // following fields are used only for kill creature/hero missions, the original // objects became inaccessible after their removal, so we need to store info diff --git a/lib/mapObjects/CRewardableObject.cpp b/lib/mapObjects/CRewardableObject.cpp index 1cade310f..560960aa1 100644 --- a/lib/mapObjects/CRewardableObject.cpp +++ b/lib/mapObjects/CRewardableObject.cpp @@ -455,7 +455,7 @@ void CRewardInfo::loadComponents(std::vector & comps, comps.emplace_back(Component::EComponentType::SPELL, entry, 1, 0); for(const auto & entry : creatures) - comps.emplace_back(Component::EComponentType::CREATURE, entry.type->idNumber, entry.count, 0); + comps.emplace_back(Component::EComponentType::CREATURE, entry.type->getId(), entry.count, 0); for (size_t i=0; icreatures.back().second.push_back(cre->idNumber); + obj->creatures.back().second.push_back(cre->getId()); } return obj; } @@ -194,7 +194,7 @@ void CDwellingInstanceConstructor::configureObject(CGObjectInstance * object, CR { dwelling->creatures.resize(dwelling->creatures.size() + 1); for(const CCreature * cre : entry) - dwelling->creatures.back().second.push_back(cre->idNumber); + dwelling->creatures.back().second.push_back(cre->getId()); } bool guarded = false; //TODO: serialize for sanity @@ -210,14 +210,14 @@ void CDwellingInstanceConstructor::configureObject(CGObjectInstance * object, CR { for(auto & stack : JsonRandom::loadCreatures(guards, rng)) { - dwelling->putStack(SlotID(dwelling->stacksCount()), new CStackInstance(stack.type->idNumber, stack.count)); + dwelling->putStack(SlotID(dwelling->stacksCount()), new CStackInstance(stack.type->getId(), stack.count)); } } else //default condition - creatures are of level 5 or higher { for(auto creatureEntry : availableCreatures) { - if(creatureEntry.at(0)->level >= 5) + if(creatureEntry.at(0)->getLevel() >= 5) { guarded = true; break; @@ -230,7 +230,7 @@ void CDwellingInstanceConstructor::configureObject(CGObjectInstance * object, CR for(auto creatureEntry : availableCreatures) { const CCreature * crea = creatureEntry.at(0); - dwelling->putStack(SlotID(dwelling->stacksCount()), new CStackInstance(crea->idNumber, crea->growth * 3)); + dwelling->putStack(SlotID(dwelling->stacksCount()), new CStackInstance(crea->getId(), crea->getGrowth() * 3)); } } } @@ -292,7 +292,7 @@ BankConfig CBankInstanceConstructor::generateConfig(const JsonNode & level, CRan for (size_t i=0; i<6; i++) IObjectInterface::cb->getAllowedSpells(spells, static_cast(i)); - bc.resources = Res::ResourceSet(level["reward"]["resources"]); + bc.resources = ResourceSet(level["reward"]["resources"]); bc.creatures = JsonRandom::loadCreatures(level["reward"]["creatures"], rng); bc.artifacts = JsonRandom::loadArtifacts(level["reward"]["artifacts"], rng); bc.spells = JsonRandom::loadSpells(level["reward"]["spells"], rng, spells); @@ -336,21 +336,21 @@ CBankInfo::CBankInfo(const JsonVector & Config) : static void addStackToArmy(IObjectInfo::CArmyStructure & army, const CCreature * crea, si32 amount) { - army.totalStrength += crea->fightValue * amount; + army.totalStrength += crea->getFightValue() * amount; bool walker = true; if(crea->hasBonusOfType(Bonus::SHOOTER)) { - army.shootersStrength += crea->fightValue * amount; + army.shootersStrength += crea->getFightValue() * amount; walker = false; } if(crea->hasBonusOfType(Bonus::FLYING)) { - army.flyersStrength += crea->fightValue * amount; + army.flyersStrength += crea->getFightValue() * amount; walker = false; } if(walker) - army.walkersStrength += crea->fightValue * amount; + army.walkersStrength += crea->getFightValue() * amount; } IObjectInfo::CArmyStructure CBankInfo::minGuards() const @@ -365,7 +365,7 @@ IObjectInfo::CArmyStructure CBankInfo::minGuards() const assert(!stack.allowedCreatures.empty()); auto weakest = boost::range::min_element(stack.allowedCreatures, [](const CCreature * a, const CCreature * b) { - return a->fightValue < b->fightValue; + return a->getFightValue() < b->getFightValue(); }); addStackToArmy(army, *weakest, stack.minAmount); } @@ -386,7 +386,7 @@ IObjectInfo::CArmyStructure CBankInfo::maxGuards() const assert(!stack.allowedCreatures.empty()); auto strongest = boost::range::max_element(stack.allowedCreatures, [](const CCreature * a, const CCreature * b) { - return a->fightValue < b->fightValue; + return a->getFightValue() < b->getFightValue(); }); addStackToArmy(army, *strongest, stack.maxAmount); } @@ -408,7 +408,7 @@ TPossibleGuards CBankInfo::getPossibleGuards() const for(auto stack : stacks) { - army.totalStrength += stack.allowedCreatures.front()->AIValue * (stack.minAmount + stack.maxAmount) / 2; + army.totalStrength += stack.allowedCreatures.front()->getAIValue() * (stack.minAmount + stack.maxAmount) / 2; //TODO: add fields for flyers, walkers etc... } diff --git a/lib/mapObjects/CommonConstructors.h b/lib/mapObjects/CommonConstructors.h index 931946725..b20693d6b 100644 --- a/lib/mapObjects/CommonConstructors.h +++ b/lib/mapObjects/CommonConstructors.h @@ -147,7 +147,7 @@ struct BankConfig ui32 upgradeChance = 0; //chance for creatures to be in upgraded versions ui32 combatValue = 0; //how hard are guards of this level std::vector guards; //creature ID, amount - Res::ResourceSet resources; //resources given in case of victory + ResourceSet resources; //resources given in case of victory std::vector creatures; //creatures granted in case of victory (creature ID, amount) std::vector artifacts; //artifacts given in case of victory std::vector spells; // granted spell(s), for Pyramid diff --git a/lib/mapObjects/MiscObjects.cpp b/lib/mapObjects/MiscObjects.cpp index da7b13ca8..743d872fa 100644 --- a/lib/mapObjects/MiscObjects.cpp +++ b/lib/mapObjects/MiscObjects.cpp @@ -287,13 +287,13 @@ int CGCreature::takenAction(const CGHeroInstance *h, bool allowJoin) const std::set myKindCres; //what creatures are the same kind as we const CCreature * myCreature = VLC->creh->objects[subID]; - myKindCres.insert(myCreature->idNumber); //we + myKindCres.insert(myCreature->getId()); //we myKindCres.insert(myCreature->upgrades.begin(), myCreature->upgrades.end()); //our upgrades for(ConstTransitivePtr &crea : VLC->creh->objects) { - if(vstd::contains(crea->upgrades, myCreature->idNumber)) //it's our base creatures - myKindCres.insert(crea->idNumber); + if(vstd::contains(crea->upgrades, myCreature->getId())) //it's our base creatures + myKindCres.insert(crea->getId()); } int count = 0; //how many creatures of similar kind has hero @@ -301,7 +301,7 @@ int CGCreature::takenAction(const CGHeroInstance *h, bool allowJoin) const for(const auto & elem : h->Slots()) { - if(vstd::contains(myKindCres,elem.second->type->idNumber)) + if(vstd::contains(myKindCres,elem.second->type->getId())) count += elem.second->count; totalCount += elem.second->count; } @@ -324,7 +324,7 @@ int CGCreature::takenAction(const CGHeroInstance *h, bool allowJoin) const return JOIN_FOR_FREE; else if(diplomacy * 2 + sympathy + 1 >= character) - return VLC->creh->objects[subID]->cost[6] * getStackCount(SlotID(0)); //join for gold + return VLC->creatures()->getByIndex(subID)->getRecruitCost(EGameResID::GOLD) * getStackCount(SlotID(0)); //join for gold } //we are still here - creatures have not joined hero, flee or fight @@ -367,7 +367,7 @@ void CGCreature::joinDecision(const CGHeroInstance *h, int cost, ui32 accept) co } else //accepted { - if (cb->getResource(h->tempOwner, Res::GOLD) < cost) //player don't have enough gold! + if (cb->getResource(h->tempOwner, EGameResID::GOLD) < cost) //player don't have enough gold! { InfoWindow iw; iw.player = h->tempOwner; @@ -381,7 +381,7 @@ void CGCreature::joinDecision(const CGHeroInstance *h, int cost, ui32 accept) co //take gold if(cost) - cb->giveResource(h->tempOwner,Res::GOLD,-cost); + cb->giveResource(h->tempOwner,EGameResID::GOLD,-cost); giveReward(h); cb->tryJoiningArmy(this, h, true, true); @@ -392,7 +392,7 @@ void CGCreature::fight( const CGHeroInstance *h ) const { //split stacks //TODO: multiple creature types in a stack? - int basicType = stacks.begin()->second->type->idNumber; + int basicType = stacks.begin()->second->type->getId(); cb->setObjProperty(id, ObjProperty::MONSTER_RESTORE_TYPE, basicType); //store info about creature stack int stacksCount = getNumberOfStacks(h); @@ -665,10 +665,10 @@ void CGMine::initObj(CRandomGenerator & rand) putStack(SlotID(0), troglodytes); //after map reading tempOwner placeholds bitmask for allowed resources - std::vector possibleResources; + std::vector possibleResources; for (int i = 0; i < PlayerColor::PLAYER_LIMIT_I; i++) if(tempOwner.getNum() & 1<(i)); + possibleResources.push_back(GameResID(i)); assert(!possibleResources.empty()); producedResource = *RandomGeneratorUtil::nextItem(possibleResources, rand); @@ -676,7 +676,7 @@ void CGMine::initObj(CRandomGenerator & rand) } else { - producedResource = static_cast(subID); + producedResource = GameResID(subID); if(tempOwner >= PlayerColor::PLAYER_LIMIT) tempOwner = PlayerColor::NEUTRAL; } @@ -719,7 +719,7 @@ void CGMine::flagMine(const PlayerColor & player) const InfoWindow iw; iw.type = EInfoWindowMode::AUTO; iw.soundID = soundBase::FLAGMINE; - iw.text.addTxt(MetaString::MINE_EVNTS,producedResource); //not use subID, abandoned mines uses default mine texts + iw.text.addTxt(MetaString::MINE_EVNTS, producedResource); //not use subID, abandoned mines uses default mine texts iw.player = player; iw.components.emplace_back(Component::EComponentType::RESOURCE, producedResource, producedQuantity, -1); cb->showInfoDialog(&iw); @@ -727,12 +727,12 @@ void CGMine::flagMine(const PlayerColor & player) const ui32 CGMine::defaultResProduction() const { - switch(producedResource) + switch(producedResource.toEnum()) { - case Res::WOOD: - case Res::ORE: + case EGameResID::WOOD: + case EGameResID::ORE: return 2; - case Res::GOLD: + case EGameResID::GOLD: return 1000; default: return 1; @@ -786,7 +786,7 @@ void CGMine::serializeJsonOptions(JsonSerializeFormat & handler) if(node.getType() != JsonNode::JsonType::DATA_VECTOR || node.Vector().empty()) { //assume all allowed - for(int i = static_cast(Res::WOOD); i < static_cast(Res::GOLD); i++) + for(int i = static_cast(EGameResID::WOOD); i < static_cast(EGameResID::GOLD); i++) possibleResources.insert(i); } else @@ -827,12 +827,12 @@ void CGResource::initObj(CRandomGenerator & rand) if(amount == CGResource::RANDOM_AMOUNT) { - switch(subID) + switch(static_cast(subID)) { - case Res::GOLD: + case EGameResID::GOLD: amount = rand.nextInt(5, 10) * 100; break; - case Res::WOOD: case Res::ORE: + case EGameResID::WOOD: case EGameResID::ORE: amount = rand.nextInt(6, 10); break; default: @@ -864,7 +864,7 @@ void CGResource::onHeroVisit( const CGHeroInstance * h ) const void CGResource::collectRes(const PlayerColor & player) const { - cb->giveResource(player, static_cast(subID), amount); + cb->giveResource(player, static_cast(subID), amount); InfoWindow sii; sii.player = player; if(!message.empty()) @@ -1986,7 +1986,7 @@ void CCartographer::onHeroVisit( const CGHeroInstance * h ) const //if player has not bought map of this subtype yet and underground exist for stalagmite cartographer if (!wasVisited(h->getOwner()) && (subID != 2 || cb->gameState()->map->twoLevel)) { - if (cb->getResource(h->tempOwner, Res::GOLD) >= 1000) //if he can afford a map + if (cb->getResource(h->tempOwner, EGameResID::GOLD) >= 1000) //if he can afford a map { //ask if he wants to buy one int text=0; @@ -2025,7 +2025,7 @@ void CCartographer::blockingDialogAnswered(const CGHeroInstance *hero, ui32 answ { if(answer) //if hero wants to buy map { - cb->giveResource(hero->tempOwner, Res::GOLD, -1000); + cb->giveResource(hero->tempOwner, EGameResID::GOLD, -1000); FoWChange fw; fw.mode = 1; fw.player = hero->tempOwner; diff --git a/lib/mapObjects/MiscObjects.h b/lib/mapObjects/MiscObjects.h index cfa0e23c1..edd0ca15d 100644 --- a/lib/mapObjects/MiscObjects.h +++ b/lib/mapObjects/MiscObjects.h @@ -263,7 +263,7 @@ protected: class DLL_LINKAGE CGMine : public CArmedInstance { public: - Res::ERes producedResource; + GameResID producedResource; ui32 producedQuantity; private: diff --git a/lib/mapping/MapFormatH3M.cpp b/lib/mapping/MapFormatH3M.cpp index 302a6e862..d5249f5c4 100644 --- a/lib/mapping/MapFormatH3M.cpp +++ b/lib/mapping/MapFormatH3M.cpp @@ -1256,7 +1256,7 @@ void CMapLoaderH3M::readObjects() readMessageAndGuards(res->message, res, objPos); res->amount = reader->readUInt32(); - if(objTempl->subid == Res::GOLD) + if(objTempl->subid == GameResID(EGameResID::GOLD)) { // Gold is multiplied by 100. res->amount *= 100; @@ -1916,11 +1916,9 @@ void CMapLoaderH3M::readQuest(IQuestObject * guard, const int3 & position) } case CQuest::MISSION_RESOURCES: { - guard->quest->m7resources.resize(7); for(int x = 0; x < 7; ++x) - { guard->quest->m7resources[x] = reader->readUInt32(); - } + break; } case CQuest::MISSION_HERO: diff --git a/lib/rmg/MinePlacer.cpp b/lib/rmg/MinePlacer.cpp index dfe61522a..8fa889987 100644 --- a/lib/rmg/MinePlacer.cpp +++ b/lib/rmg/MinePlacer.cpp @@ -44,14 +44,13 @@ void MinePlacer::init() bool MinePlacer::placeMines(ObjectManager & manager) { - using namespace Res; std::vector createdMines; std::vector> requiredObjects; for(const auto & mineInfo : zone.getMinesInfo()) { - ERes res = static_cast(mineInfo.first); + const auto res = GameResID(mineInfo.first); for(int i = 0; i < mineInfo.second; ++i) { auto mineHandler = VLC->objtypeh->getHandlerFor(Obj::MINE, res); @@ -63,7 +62,7 @@ bool MinePlacer::placeMines(ObjectManager & manager) createdMines.push_back(mine); - if(!i && (res == ERes::WOOD || res == ERes::ORE)) + if(!i && (res == EGameResID::WOOD || res == EGameResID::ORE)) manager.addCloseObject(mine, rmginfo.value); //only first wood&ore mines are close else requiredObjects.push_back(std::pair(mine, rmginfo.value)); diff --git a/lib/rmg/ObjectManager.cpp b/lib/rmg/ObjectManager.cpp index 5143706d4..75783c369 100644 --- a/lib/rmg/ObjectManager.cpp +++ b/lib/rmg/ObjectManager.cpp @@ -424,26 +424,26 @@ CGCreature * ObjectManager::chooseGuard(si32 strength, bool zoneGuard) { if(cre->special) continue; - if(!cre->AIValue) //bug #2681 + if(!cre->getAIValue()) //bug #2681 continue; - if(!vstd::contains(zone.getMonsterTypes(), cre->faction)) + if(!vstd::contains(zone.getMonsterTypes(), cre->getFactionIndex())) continue; - if((static_cast(cre->AIValue * (cre->ammMin + cre->ammMax) / 2) < strength) && (strength < static_cast(cre->AIValue) * 100)) //at least one full monster. size between average size of given stack and 100 + if((static_cast(cre->getAIValue() * (cre->ammMin + cre->ammMax) / 2) < strength) && (strength < static_cast(cre->getAIValue()) * 100)) //at least one full monster. size between average size of given stack and 100 { - possibleCreatures.push_back(cre->idNumber); + possibleCreatures.push_back(cre->getId()); } } if(!possibleCreatures.empty()) { creId = *RandomGeneratorUtil::nextItem(possibleCreatures, generator.rand); - amount = strength / VLC->creh->objects[creId]->AIValue; + amount = strength / VLC->creh->objects[creId]->getAIValue(); if (amount >= 4) amount = static_cast(amount * generator.rand.nextDouble(0.75, 1.25)); } else //just pick any available creature { creId = CreatureID(132); //Azure Dragon - amount = strength / VLC->creh->objects[creId]->AIValue; + amount = strength / VLC->creh->objects[creId]->getAIValue(); } auto guardFactory = VLC->objtypeh->getHandlerFor(Obj::MONSTER, creId); diff --git a/lib/rmg/TreasurePlacer.cpp b/lib/rmg/TreasurePlacer.cpp index ab4efc7b7..6a5e43f0b 100644 --- a/lib/rmg/TreasurePlacer.cpp +++ b/lib/rmg/TreasurePlacer.cpp @@ -135,7 +135,7 @@ void TreasurePlacer::addAllPossibleObjects() std::vector creatures; //native creatures for this zone for(auto cre : VLC->creh->objects) { - if(!cre->special && cre->faction == zone.getTownType()) + if(!cre->special && cre->getFactionIndex() == zone.getTownType()) { creatures.push_back(cre); } @@ -164,10 +164,10 @@ void TreasurePlacer::addAllPossibleObjects() continue; const auto * cre = creatures.front(); - if(cre->faction == zone.getTownType()) + if(cre->getFactionIndex() == zone.getTownType()) { - auto nativeZonesCount = static_cast(map.getZoneCount(cre->faction)); - oi.value = static_cast(cre->AIValue * cre->growth * (1 + (nativeZonesCount / map.getTotalZoneCount()) + (nativeZonesCount / 2))); + auto nativeZonesCount = static_cast(map.getZoneCount(cre->getFactionIndex())); + oi.value = static_cast(cre->getAIValue() * cre->getGrowth() * (1 + (nativeZonesCount / map.getTotalZoneCount()) + (nativeZonesCount / 2))); oi.probability = 40; for(const auto & tmplate : dwellingHandler->getTemplates()) @@ -221,7 +221,7 @@ void TreasurePlacer::addAllPossibleObjects() { auto factory = VLC->objtypeh->getHandlerFor(Obj::PANDORAS_BOX, 0); auto * obj = dynamic_cast(factory->create()); - obj->resources[Res::GOLD] = i * 5000; + obj->resources[EGameResID::GOLD] = i * 5000; return obj; }; oi.setTemplate(Obj::PANDORAS_BOX, 0, zone.getTerrainType()); @@ -251,13 +251,13 @@ void TreasurePlacer::addAllPossibleObjects() auto creatureToCount = [tierValues](CCreature * creature) -> int { - if(!creature->AIValue || tierValues.empty()) //bug #2681 + if(!creature->getAIValue() || tierValues.empty()) //bug #2681 return 0; //this box won't be generated - int actualTier = creature->level > tierValues.size() ? + int actualTier = creature->getLevel() > tierValues.size() ? tierValues.size() - 1 : - creature->level - 1; - float creaturesAmount = (static_cast(tierValues[actualTier])) / creature->AIValue; + creature->getLevel() - 1; + float creaturesAmount = (static_cast(tierValues[actualTier])) / creature->getAIValue(); if(creaturesAmount <= 5) { creaturesAmount = boost::math::round(creaturesAmount); //allow single monsters @@ -294,7 +294,7 @@ void TreasurePlacer::addAllPossibleObjects() return obj; }; oi.setTemplate(Obj::PANDORAS_BOX, 0, zone.getTerrainType()); - oi.value = static_cast((2 * (creature->AIValue) * creaturesAmount * (1 + static_cast(map.getZoneCount(creature->faction)) / map.getTotalZoneCount())) / 3); + oi.value = static_cast((2 * (creature->getAIValue()) * creaturesAmount * (1 + static_cast(map.getZoneCount(creature->getFactionIndex())) / map.getTotalZoneCount())) / 3); oi.probability = 3; addObjectToRandomPool(oi); } @@ -436,7 +436,7 @@ void TreasurePlacer::addAllPossibleObjects() auto factory = VLC->objtypeh->getHandlerFor(Obj::SEER_HUT, randomAppearance); auto * obj = dynamic_cast(factory->create()); obj->rewardType = CGSeerHut::CREATURE; - obj->rID = creature->idNumber; + obj->rID = creature->getId(); obj->rVal = creaturesAmount; obj->quest->missionType = CQuest::MISSION_ART; @@ -453,7 +453,7 @@ void TreasurePlacer::addAllPossibleObjects() return obj; }; oi.setTemplate(Obj::SEER_HUT, randomAppearance, zone.getTerrainType()); - oi.value = static_cast(((2 * (creature->AIValue) * creaturesAmount * (1 + static_cast(map.getZoneCount(creature->faction)) / map.getTotalZoneCount())) - 4000) / 3); + oi.value = static_cast(((2 * (creature->getAIValue()) * creaturesAmount * (1 + static_cast(map.getZoneCount(creature->getFactionIndex())) / map.getTotalZoneCount())) - 4000) / 3); oi.probability = 3; addObjectToRandomPool(oi); } @@ -496,7 +496,7 @@ void TreasurePlacer::addAllPossibleObjects() auto factory = VLC->objtypeh->getHandlerFor(Obj::SEER_HUT, randomAppearance); auto * obj = dynamic_cast(factory->create()); obj->rewardType = CGSeerHut::RESOURCES; - obj->rID = Res::GOLD; + obj->rID = GameResID(EGameResID::GOLD); obj->rVal = generator.getConfig().questRewardValues[i]; obj->quest->missionType = CQuest::MISSION_ART; diff --git a/lib/serializer/CSerializer.cpp b/lib/serializer/CSerializer.cpp index a26a7246b..7e5df525c 100644 --- a/lib/serializer/CSerializer.cpp +++ b/lib/serializer/CSerializer.cpp @@ -29,7 +29,7 @@ void CSerializer::addStdVecItems(CGameState *gs, LibClasses *lib) registerVectoredType(&gs->map->allHeroes, [](const CGHeroInstance &h){ return h.type->getId(); }); registerVectoredType(&lib->creh->objects, - [](const CCreature &cre){ return cre.idNumber; }); + [](const CCreature &cre){ return cre.getId(); }); registerVectoredType(&lib->arth->objects, [](const CArtifact &art){ return art.getId(); }); registerVectoredType(&gs->map->artInstances, diff --git a/mapeditor/inspector/inspector.cpp b/mapeditor/inspector/inspector.cpp index 2e96b3179..edf87e94c 100644 --- a/mapeditor/inspector/inspector.cpp +++ b/mapeditor/inspector/inspector.cpp @@ -181,7 +181,7 @@ void Initializer::initialize(CGMine * o) if(!o) return; o->tempOwner = defaultPlayer; - o->producedResource = Res::ERes(o->subID); + o->producedResource = GameResID(o->subID); o->producedQuantity = o->defaultResProduction(); } @@ -701,29 +701,29 @@ QTableWidgetItem * Inspector::addProperty(const PlayerColor & value) return new QTableWidgetItem(str); } -QTableWidgetItem * Inspector::addProperty(const Res::ERes & value) +QTableWidgetItem * Inspector::addProperty(const GameResID & value) { QString str; - switch (value) { - case Res::ERes::WOOD: + switch (value.toEnum()) { + case EGameResID::WOOD: str = "WOOD"; break; - case Res::ERes::ORE: + case EGameResID::ORE: str = "ORE"; break; - case Res::ERes::SULFUR: + case EGameResID::SULFUR: str = "SULFUR"; break; - case Res::ERes::GEMS: + case EGameResID::GEMS: str = "GEMS"; break; - case Res::ERes::MERCURY: + case EGameResID::MERCURY: str = "MERCURY"; break; - case Res::ERes::CRYSTAL: + case EGameResID::CRYSTAL: str = "CRYSTAL"; break; - case Res::ERes::GOLD: + case EGameResID::GOLD: str = "GOLD"; break; default: diff --git a/mapeditor/inspector/inspector.h b/mapeditor/inspector/inspector.h index b183243b7..96e338db2 100644 --- a/mapeditor/inspector/inspector.h +++ b/mapeditor/inspector/inspector.h @@ -83,7 +83,7 @@ protected: QTableWidgetItem * addProperty(const QString & value); QTableWidgetItem * addProperty(const int3 & value); QTableWidgetItem * addProperty(const PlayerColor & value); - QTableWidgetItem * addProperty(const Res::ERes & value); + QTableWidgetItem * addProperty(const GameResID & value); QTableWidgetItem * addProperty(bool value); QTableWidgetItem * addProperty(CGObjectInstance * value); QTableWidgetItem * addProperty(CGCreature::Character value); diff --git a/mapeditor/inspector/questwidget.cpp b/mapeditor/inspector/questwidget.cpp index 747a9c7a7..ba2af6a38 100644 --- a/mapeditor/inspector/questwidget.cpp +++ b/mapeditor/inspector/questwidget.cpp @@ -141,7 +141,6 @@ QString QuestWidget::commitChanges() //TODO: implement return QString("N/A"); case CQuest::Emission::MISSION_RESOURCES: - seerhut.quest->m7resources.resize(sizeof(GameConstants::RESOURCE_NAMES), 0); seerhut.quest->m7resources[ui->targetId->currentIndex()] = ui->targetAmount->text().toInt(); //TODO: support resources return ui->targetId->currentText().append(ui->targetAmount->text()); diff --git a/mapeditor/inspector/rewardswidget.cpp b/mapeditor/inspector/rewardswidget.cpp index c0dd92fa2..a8f01cf05 100644 --- a/mapeditor/inspector/rewardswidget.cpp +++ b/mapeditor/inspector/rewardswidget.cpp @@ -132,7 +132,7 @@ void RewardsWidget::obtainData() addReward(RewardType::LUCK, 0, pandora->luckDiff); if(pandora->resources.nonZero()) { - for(Res::ResourceSet::nziterator resiter(pandora->resources); resiter.valid(); ++resiter) + for(ResourceSet::nziterator resiter(pandora->resources); resiter.valid(); ++resiter) addReward(RewardType::RESOURCE, resiter->resType, resiter->resVal); } for(int idx = 0; idx < pandora->primskills.size(); ++idx) @@ -218,7 +218,7 @@ bool RewardsWidget::commitChanges() pandora->abilities.clear(); pandora->abilityLevels.clear(); pandora->primskills.resize(GameConstants::PRIMARY_SKILLS, 0); - pandora->resources = Res::ResourceSet(); + pandora->resources = ResourceSet(); pandora->artifacts.clear(); pandora->spells.clear(); pandora->creatures.clear(); diff --git a/scripting/lua/api/Artifact.cpp b/scripting/lua/api/Artifact.cpp index 0fe72a1c9..9c7695f66 100644 --- a/scripting/lua/api/Artifact.cpp +++ b/scripting/lua/api/Artifact.cpp @@ -34,7 +34,7 @@ const std::vector ArtifactProxy::REGISTER_CUSTOM = {"getName", LuaMethodWrapper::invoke, false}, {"getId", LuaMethodWrapper::getId), &EntityT::getId>::invoke, false}, - {"accessBonuses", LuaMethodWrapper::accessBonuses), &EntityWithBonuses::accessBonuses>::invoke, false}, + {"getBonusBearer", LuaMethodWrapper::getBonusBearer), &EntityWithBonuses::getBonusBearer>::invoke, false}, {"getDescription", LuaMethodWrapper::invoke, false}, {"getEventText", LuaMethodWrapper::invoke, false}, diff --git a/scripting/lua/api/Creature.cpp b/scripting/lua/api/Creature.cpp index bf6ed9e9c..b11b8a29b 100644 --- a/scripting/lua/api/Creature.cpp +++ b/scripting/lua/api/Creature.cpp @@ -32,7 +32,7 @@ const std::vector CreatureProxy::REGISTER_CUSTOM = {"getIndex", LuaMethodWrapper::invoke, false}, {"getJsonKey", LuaMethodWrapper::invoke, false}, {"getName", LuaMethodWrapper::invoke, false}, - {"accessBonuses", LuaMethodWrapper::accessBonuses), &EntityWithBonuses::accessBonuses>::invoke, false}, + {"getBonusBearer", LuaMethodWrapper::getBonusBearer), &EntityWithBonuses::getBonusBearer>::invoke, false}, {"getMaxHealth", LuaMethodWrapper::invoke, false}, {"getPluralName", LuaMethodWrapper::invoke, false}, @@ -56,7 +56,7 @@ const std::vector CreatureProxy::REGISTER_CUSTOM = {"getBaseSpeed", LuaMethodWrapper::invoke, false}, {"getBaseShots", LuaMethodWrapper::invoke, false}, - {"getCost", LuaMethodWrapper::invoke, false}, + {"getRecruitCost", LuaMethodWrapper::invoke, false}, {"isDoubleWide", LuaMethodWrapper::invoke, false}, }; diff --git a/scripting/lua/api/Creature.h b/scripting/lua/api/Creature.h index f13a81296..af14a4cfb 100644 --- a/scripting/lua/api/Creature.h +++ b/scripting/lua/api/Creature.h @@ -10,10 +10,10 @@ #pragma once -#include - #include "../LuaWrapper.h" +#include + VCMI_LIB_NAMESPACE_BEGIN namespace scripting diff --git a/scripting/lua/api/Player.cpp b/scripting/lua/api/Player.cpp index f5d0c12ef..cd518d481 100644 --- a/scripting/lua/api/Player.cpp +++ b/scripting/lua/api/Player.cpp @@ -29,7 +29,7 @@ const std::vector PlayerProxy::REGISTER_CUSTOM = // virtual PlayerColor getColor() const = 0; // virtual TeamID getTeam() const = 0; // virtual bool isHuman() const = 0; -// virtual const IBonusBearer * accessBonuses() const = 0; +// virtual const IBonusBearer * getBonusBearer() const = 0; // virtual int getResourceAmount(int type) const = 0; }; diff --git a/scripting/lua/api/netpacks/SetResources.cpp b/scripting/lua/api/netpacks/SetResources.cpp index 055bd736f..2d8b5c569 100644 --- a/scripting/lua/api/netpacks/SetResources.cpp +++ b/scripting/lua/api/netpacks/SetResources.cpp @@ -102,7 +102,7 @@ int SetResourcesProxy::getAmount(lua_State * L) if(!S.tryGet(1, object)) return S.retVoid(); - Res::ERes type = Res::ERes::INVALID; + auto type = EGameResID::INVALID; if(!S.tryGet(2, type)) return S.retVoid(); @@ -122,7 +122,7 @@ int SetResourcesProxy::setAmount(lua_State * L) if(!S.tryGet(1, object)) return S.retVoid(); - Res::ERes type = Res::ERes::INVALID; + auto type = EGameResID::INVALID; if(!S.tryGet(2, type)) return S.retVoid(); diff --git a/scripts/lib/erm/MA.lua b/scripts/lib/erm/MA.lua index 4e12fca90..4c4dcc295 100644 --- a/scripts/lib/erm/MA.lua +++ b/scripts/lib/erm/MA.lua @@ -149,7 +149,7 @@ end function MA:X(x, creatureIndex, flagsMask) local creatureIndex = checkCreatureIndex(creatureIndex) local creature = creatureByIndex(creatureIndex) - local creatureBonuses = creature:accessBonuses() + local creatureBonuses = creature:getBonusBearer() local all = creatureBonuses:getBonuses() local currentMask = 0 diff --git a/server/CGameHandler.cpp b/server/CGameHandler.cpp index 02ec4b87b..0085285ac 100644 --- a/server/CGameHandler.cpp +++ b/server/CGameHandler.cpp @@ -1643,11 +1643,11 @@ void CGameHandler::setPortalDwelling(const CGTownInstance * town, bool forced=fa if (clear) { - ssi.creatures[GameConstants::CREATURES_PER_TOWN].first = std::max((ui32)1, (VLC->creh->objects.at(creatureId)->growth)/2); + ssi.creatures[GameConstants::CREATURES_PER_TOWN].first = std::max(1, (VLC->creh->objects.at(creatureId)->getGrowth())/2); } else { - ssi.creatures[GameConstants::CREATURES_PER_TOWN].first = VLC->creh->objects.at(creatureId)->growth; + ssi.creatures[GameConstants::CREATURES_PER_TOWN].first = VLC->creh->objects.at(creatureId)->getGrowth(); } ssi.creatures[GameConstants::CREATURES_PER_TOWN].second.push_back(creatureId); sendAndApply(&ssi); @@ -1732,7 +1732,7 @@ void CGameHandler::newTurn() { newMonster.second = VLC->creh->pickRandomMonster(getRandomGenerator()); } while (VLC->creh->objects[newMonster.second] && - (*VLC->townh)[(*VLC->creh)[newMonster.second]->faction]->town == nullptr); // find first non neutral creature + (*VLC->townh)[VLC->creatures()->getById(newMonster.second)->getFactionIndex()]->town == nullptr); // find first non neutral creature n.creatureid = newMonster.second; } } @@ -1767,7 +1767,7 @@ void CGameHandler::newTurn() else if (elem.first >= PlayerColor::PLAYER_LIMIT) assert(0); //illegal player number! - std::pair playerGold(elem.first, elem.second.resources[Res::GOLD]); + std::pair playerGold(elem.first, elem.second.resources[EGameResID::GOLD]); hadGold.insert(playerGold); if (newWeek) //new heroes in tavern @@ -1826,7 +1826,7 @@ void CGameHandler::newTurn() } } if(hasCrystalGenCreature) - n.res[elem.first][Res::CRYSTAL] += 3; + n.res[elem.first][EGameResID::CRYSTAL] += 3; } for (CGHeroInstance *h : (elem).second.heroes) @@ -1863,7 +1863,7 @@ void CGameHandler::newTurn() if (!firstTurn) if (t->hasBuilt(BuildingSubID::TREASURY) && player < PlayerColor::PLAYER_LIMIT) - n.res[player][Res::GOLD] += hadGold.at(player)/10; //give 10% of starting gold + n.res[player][EGameResID::GOLD] += hadGold.at(player)/10; //give 10% of starting gold if (!vstd::contains(n.cres, t->id)) { @@ -1884,7 +1884,7 @@ void CGameHandler::newTurn() else { if (firstTurn) //first day of game: use only basic growths - availableCount = cre->growth; + availableCount = cre->getGrowth(); else availableCount += t->creatureGrowth(k); @@ -1892,7 +1892,7 @@ void CGameHandler::newTurn() if (n.specialWeek == NewTurn::DEITYOFFIRE && vstd::contains(t->creatures.at(k).second, n.creatureid)) availableCount += 15; - if (cre->idNumber == n.creatureid) //bonus week, effect applies only to identical creatures + if (cre->getId() == n.creatureid) //bonus week, effect applies only to identical creatures { if (n.specialWeek == NewTurn::DOUBLE_GROWTH) availableCount *= 2; @@ -2495,7 +2495,7 @@ void CGameHandler::showTeleportDialog(TeleportDialog *iw) sendToAllClients(iw); } -void CGameHandler::giveResource(PlayerColor player, Res::ERes which, int val) //TODO: cap according to Bersy's suggestion +void CGameHandler::giveResource(PlayerColor player, GameResID which, int val) //TODO: cap according to Bersy's suggestion { if (!val) return; //don't waste time on empty call @@ -3452,8 +3452,8 @@ bool CGameHandler::buildStructure(ObjectInstanceID tid, BuildingID requestedID, ssi.tid = t->id; ssi.creatures = t->creatures; if (ssi.creatures[level].second.empty()) // first creature in a dwelling - ssi.creatures[level].first = crea->growth; - ssi.creatures[level].second.push_back(crea->idNumber); + ssi.creatures[level].first = crea->getGrowth(); + ssi.creatures[level].second.push_back(crea->getId()); sendAndApply(&ssi); } if(t->town->buildings.at(buildingID)->subId == BuildingSubID::PORTAL_OF_SUMMONING) @@ -3630,7 +3630,7 @@ bool CGameHandler::recruitCreatures(ObjectInstanceID objid, ObjectInstanceID dst } //recruit - giveResources(dst->tempOwner, -(c->cost * cram)); + giveResources(dst->tempOwner, -(c->getFullRecruitCost() * cram)); SetAvailableCreatures sac; sac.tid = objid; @@ -3702,7 +3702,7 @@ bool CGameHandler::changeStackType(const StackLocation &sl, const CCreature *c) SetStackType sst; sst.army = sl.army->id; sst.slot = sl.slot; - sst.type = c->idNumber; + sst.type = c->getId(); sendAndApply(&sst); return true; } @@ -4044,12 +4044,12 @@ bool CGameHandler::buyArtifact(ObjectInstanceID hid, ArtifactID aid) if (aid==ArtifactID::SPELLBOOK) { if ((!town->hasBuilt(BuildingID::MAGES_GUILD_1) && complain("Cannot buy a spellbook, no mage guild in the town!")) - || (getResource(hero->getOwner(), Res::GOLD) < GameConstants::SPELLBOOK_GOLD_COST && complain("Cannot buy a spellbook, not enough gold!")) + || (getResource(hero->getOwner(), EGameResID::GOLD) < GameConstants::SPELLBOOK_GOLD_COST && complain("Cannot buy a spellbook, not enough gold!")) || (hero->getArt(ArtifactPosition::SPELLBOOK) && complain("Cannot buy a spellbook, hero already has a one!")) ) return false; - giveResource(hero->getOwner(),Res::GOLD,-GameConstants::SPELLBOOK_GOLD_COST); + giveResource(hero->getOwner(),EGameResID::GOLD,-GameConstants::SPELLBOOK_GOLD_COST); giveHeroNewArtifact(hero, VLC->arth->objects[ArtifactID::SPELLBOOK], ArtifactPosition::SPELLBOOK); assert(hero->getArt(ArtifactPosition::SPELLBOOK)); giveSpells(town,hero); @@ -4062,12 +4062,12 @@ bool CGameHandler::buyArtifact(ObjectInstanceID hid, ArtifactID aid) COMPLAIN_RET_FALSE_IF(art->warMachine == CreatureID::NONE, "War machine artifact required"); COMPLAIN_RET_FALSE_IF(hero->hasArt(aid),"Hero already has this machine!"); const int price = art->price; - COMPLAIN_RET_FALSE_IF(getPlayerState(hero->getOwner())->resources[Res::GOLD] < price, "Not enough gold!"); + COMPLAIN_RET_FALSE_IF(getPlayerState(hero->getOwner())->resources[EGameResID::GOLD] < price, "Not enough gold!"); if ((town->hasBuilt(BuildingID::BLACKSMITH) && town->town->warMachine == aid) || (town->hasBuilt(BuildingSubID::BALLISTA_YARD) && aid == ArtifactID::BALLISTA)) { - giveResource(hero->getOwner(),Res::GOLD,-price); + giveResource(hero->getOwner(),EGameResID::GOLD,-price); return giveHeroNewArtifact(hero, art); } else @@ -4075,7 +4075,7 @@ bool CGameHandler::buyArtifact(ObjectInstanceID hid, ArtifactID aid) } } -bool CGameHandler::buyArtifact(const IMarket *m, const CGHeroInstance *h, Res::ERes rid, ArtifactID aid) +bool CGameHandler::buyArtifact(const IMarket *m, const CGHeroInstance *h, GameResID rid, ArtifactID aid) { if(!h) COMPLAIN_RET("Only hero can buy artifacts!"); @@ -4124,7 +4124,7 @@ bool CGameHandler::buyArtifact(const IMarket *m, const CGHeroInstance *h, Res::E return true; } -bool CGameHandler::sellArtifact(const IMarket *m, const CGHeroInstance *h, ArtifactInstanceID aid, Res::ERes rid) +bool CGameHandler::sellArtifact(const IMarket *m, const CGHeroInstance *h, ArtifactInstanceID aid, GameResID rid) { COMPLAIN_RET_FALSE_IF((!h), "Only hero can sell artifacts!"); const CArtifactInstance *art = h->getArtByInstanceId(aid); @@ -4156,10 +4156,10 @@ bool CGameHandler::buySecSkill(const IMarket *m, const CGHeroInstance *h, Second if (!vstd::contains(m->availableItemsIds(EMarketMode::RESOURCE_SKILL), skill)) COMPLAIN_RET("That skill is unavailable!"); - if (getResource(h->tempOwner, Res::GOLD) < GameConstants::SKILL_GOLD_COST)//TODO: remove hardcoded resource\summ? + if (getResource(h->tempOwner, EGameResID::GOLD) < GameConstants::SKILL_GOLD_COST)//TODO: remove hardcoded resource\summ? COMPLAIN_RET("You can't afford to buy this skill"); - giveResource(h->tempOwner, Res::GOLD, -GameConstants::SKILL_GOLD_COST); + giveResource(h->tempOwner, EGameResID::GOLD, -GameConstants::SKILL_GOLD_COST); changeSecSkill(h, skill, 1, true); return true; @@ -4180,13 +4180,13 @@ bool CGameHandler::tradeResources(const IMarket *market, ui32 val, PlayerColor p COMPLAIN_RET("Invalid deal, not all offered units of resource were used."); } - giveResource(player, static_cast(id1), - b1 * units); - giveResource(player, static_cast(id2), b2 * units); + giveResource(player, GameResID(id1), - b1 * units); + giveResource(player, GameResID(id2), b2 * units); return true; } -bool CGameHandler::sellCreatures(ui32 count, const IMarket *market, const CGHeroInstance * hero, SlotID slot, Res::ERes resourceID) +bool CGameHandler::sellCreatures(ui32 count, const IMarket *market, const CGHeroInstance * hero, SlotID slot, GameResID resourceID) { if(!hero) COMPLAIN_RET("Only hero can sell creatures!"); @@ -4202,7 +4202,7 @@ bool CGameHandler::sellCreatures(ui32 count, const IMarket *market, const CGHero } int b1, b2; //base quantities for trade - market->getOffer(s.type->idNumber, resourceID, b1, b2, EMarketMode::CREATURE_RESOURCE); + market->getOffer(s.type->getId(), resourceID, b1, b2, EMarketMode::CREATURE_RESOURCE); int units = count / b1; //how many base quantities we trade if (count%b1) //all offered units of resource should be used, if not -> somewhere in calculations must be an error @@ -4246,7 +4246,7 @@ bool CGameHandler::transformInUndead(const IMarket *market, const CGHeroInstance return true; } -bool CGameHandler::sendResources(ui32 val, PlayerColor player, Res::ERes r1, PlayerColor r2) +bool CGameHandler::sendResources(ui32 val, PlayerColor player, GameResID r1, PlayerColor r2) { const PlayerState *p2 = getPlayerState(r2, false); if (!p2 || p2->status != EPlayerStatus::INGAME) @@ -4288,9 +4288,9 @@ bool CGameHandler::hireHero(const CGObjectInstance *obj, ui8 hid, PlayerColor pl const CGTownInstance * t = getTown(obj->id); //common preconditions -// if ((p->resources.at(Res::GOLD)resources.at(EGameResID::GOLD)= GameConstants::MAX_HEROES_PER_PLAYER && complain("Cannot hire hero, only 8 wandering heroes are allowed!"))) - if ((p->resources[Res::GOLD] < GameConstants::HERO_GOLD_COST && complain("Not enough gold for buying hero!")) + if ((p->resources[EGameResID::GOLD] < GameConstants::HERO_GOLD_COST && complain("Not enough gold for buying hero!")) || ((getHeroCount(player, false) >= VLC->settings()->getInteger(EGameSettings::HEROES_PER_PLAYER_ON_MAP_CAP) && complain("Cannot hire hero, too many wandering heroes already!"))) || ((getHeroCount(player, true) >= VLC->settings()->getInteger(EGameSettings::HEROES_PER_PLAYER_TOTAL_CAP) && complain("Cannot hire hero, too many heroes garrizoned and wandering already!")))) { @@ -4353,7 +4353,7 @@ bool CGameHandler::hireHero(const CGObjectInstance *obj, ui8 hid, PlayerColor pl sah.hid[!hid] = theOtherHero ? theOtherHero->subID : -1; sendAndApply(&sah); - giveResource(player, Res::GOLD, -GameConstants::HERO_GOLD_COST); + giveResource(player, EGameResID::GOLD, -GameConstants::HERO_GOLD_COST); if (t) { @@ -4594,11 +4594,11 @@ bool CGameHandler::makeBattleAction(BattleAction &ba) int cost = gs->curB->battleGetSurrenderCost(player); if (cost < 0) complain("Cannot surrender!"); - else if (getResource(player, Res::GOLD) < cost) + else if (getResource(player, EGameResID::GOLD) < cost) complain("Not enough gold to surrender!"); else { - giveResource(player, Res::GOLD, -cost); + giveResource(player, EGameResID::GOLD, -cost); setBattleResult(BattleResult::SURRENDER, !ba.side); //surrendering side loses } break; @@ -5961,8 +5961,8 @@ void CGameHandler::handleAfterAttackCasting(bool ranged, const CStack * attacker int bonusAdditionalInfo = attacker->getBonus(Selector::type()(Bonus::TRANSMUTATION))->additionalInfo[0]; - if(defender->getCreature()->idNumber == bonusAdditionalInfo || - (bonusAdditionalInfo == CAddInfo::NONE && defender->getCreature()->idNumber == attacker->getCreature()->idNumber)) + if(defender->getCreature()->getId() == bonusAdditionalInfo || + (bonusAdditionalInfo == CAddInfo::NONE && defender->getCreature()->getId() == attacker->getCreature()->getId())) return; battle::UnitInfo resurrectInfo; @@ -6069,7 +6069,7 @@ bool CGameHandler::sacrificeCreatures(const IMarket * market, const CGHeroInstan COMPLAIN_RET("Cannot sacrifice last creature!"); } - int crid = hero->getStack(slot[i]).type->idNumber; + int crid = hero->getStack(slot[i]).type->getId(); changeStackCount(StackLocation(hero, slot[i]), -(TQuantity)count[i]); @@ -6150,7 +6150,7 @@ bool CGameHandler::insertNewStack(const StackLocation &sl, const CCreature *c, T InsertNewStack ins; ins.army = sl.army->id; ins.slot = sl.slot; - ins.type = c->idNumber; + ins.type = c->getId(); ins.count = count; sendAndApply(&ins); return true; @@ -6523,7 +6523,7 @@ void CGameHandler::runBattle() } const CGHeroInstance * curOwner = battleGetOwnerHero(next); - const int stackCreatureId = next->getCreature()->idNumber; + const int stackCreatureId = next->getCreature()->getId(); if ((stackCreatureId == CreatureID::ARROW_TOWERS || stackCreatureId == CreatureID::BALLISTA) && (!curOwner || getRandomGenerator().nextInt(99) >= curOwner->valOfBonuses(Bonus::MANUAL_CONTROL, stackCreatureId))) @@ -6539,7 +6539,7 @@ void CGameHandler::runBattle() for(auto & elem : gs->curB->stacks) { - if(elem->getCreature()->idNumber != CreatureID::CATAPULT + if(elem->getCreature()->getId() != CreatureID::CATAPULT && elem->owner != next->owner && elem->isValidTarget() && gs->curB->battleCanShoot(next, elem->getPosition())) @@ -6561,7 +6561,7 @@ void CGameHandler::runBattle() continue; } - if (next->getCreature()->idNumber == CreatureID::CATAPULT) + if (next->getCreature()->getId() == CreatureID::CATAPULT) { const auto & attackableBattleHexes = curB.getAttackableBattleHexes(); @@ -6583,7 +6583,7 @@ void CGameHandler::runBattle() } } - if (next->getCreature()->idNumber == CreatureID::FIRST_AID_TENT) + if (next->getCreature()->getId() == CreatureID::FIRST_AID_TENT) { TStacks possibleStacks = battleGetStacksIf([=](const CStack * s) { @@ -6988,8 +6988,8 @@ void CGameHandler::handleCheatCode(std::string & cheat, PlayerColor player, cons cheated = true; ///Give resources to player TResources resources; - resources[Res::GOLD] = 100000; - for (Res::ERes i = Res::WOOD; i < Res::GOLD; vstd::advance(i, 1)) + resources[EGameResID::GOLD] = 100000; + for (auto i = EGameResID::WOOD; i < EGameResID::GOLD; vstd::advance(i, 1)) resources[i] = 100; giveResources(player, resources); @@ -7205,7 +7205,7 @@ CasualtiesAfterBattle::CasualtiesAfterBattle(const CArmedInstance * _army, Battl if(st->alive() && st->getCount() > 0) { logGlobal->debug("Permanently summoned %d units.", st->getCount()); - const CreatureID summonedType = st->type->idNumber; + const CreatureID summonedType = st->type->getId(); summoned[summonedType] += st->getCount(); } } diff --git a/server/CGameHandler.h b/server/CGameHandler.h index 08eb79662..0cf2ccc74 100644 --- a/server/CGameHandler.h +++ b/server/CGameHandler.h @@ -160,7 +160,7 @@ public: void showTeleportDialog(TeleportDialog *iw) override; void showGarrisonDialog(ObjectInstanceID upobj, ObjectInstanceID hid, bool removableUnits) override; void showThievesGuildWindow(PlayerColor player, ObjectInstanceID requestingObjId) override; - void giveResource(PlayerColor player, Res::ERes which, int val) override; + void giveResource(PlayerColor player, GameResID which, int val) override; void giveResources(PlayerColor player, TResources resources) override; void giveCreatures(const CArmedInstance *objid, const CGHeroInstance * h, const CCreatureSet &creatures, bool remove) override; @@ -241,13 +241,13 @@ public: bool setFormation( ObjectInstanceID hid, ui8 formation ); bool tradeResources(const IMarket *market, ui32 val, PlayerColor player, ui32 id1, ui32 id2); bool sacrificeCreatures(const IMarket * market, const CGHeroInstance * hero, const std::vector & slot, const std::vector & count); - bool sendResources(ui32 val, PlayerColor player, Res::ERes r1, PlayerColor r2); - bool sellCreatures(ui32 count, const IMarket *market, const CGHeroInstance * hero, SlotID slot, Res::ERes resourceID); + bool sendResources(ui32 val, PlayerColor player, GameResID r1, PlayerColor r2); + bool sellCreatures(ui32 count, const IMarket *market, const CGHeroInstance * hero, SlotID slot, GameResID resourceID); bool transformInUndead(const IMarket *market, const CGHeroInstance * hero, SlotID slot); bool assembleArtifacts (ObjectInstanceID heroID, ArtifactPosition artifactSlot, bool assemble, ArtifactID assembleTo); bool buyArtifact( ObjectInstanceID hid, ArtifactID aid ); //for blacksmith and mage guild only -> buying for gold in common buildings - bool buyArtifact( const IMarket *m, const CGHeroInstance *h, Res::ERes rid, ArtifactID aid); //for artifact merchant and black market -> buying for any resource in special building / advobject - bool sellArtifact( const IMarket *m, const CGHeroInstance *h, ArtifactInstanceID aid, Res::ERes rid); //for artifact merchant selling + bool buyArtifact( const IMarket *m, const CGHeroInstance *h, GameResID rid, ArtifactID aid); //for artifact merchant and black market -> buying for any resource in special building / advobject + bool sellArtifact( const IMarket *m, const CGHeroInstance *h, ArtifactInstanceID aid, GameResID rid); //for artifact merchant selling //void lootArtifacts (TArtHolder source, TArtHolder dest, std::vector &arts); //after battle - move al arts to winer bool buySecSkill( const IMarket *m, const CGHeroInstance *h, SecondarySkill skill); bool garrisonSwap(ObjectInstanceID tid); diff --git a/server/NetPacksServer.cpp b/server/NetPacksServer.cpp index def5cbc7c..1dc301160 100644 --- a/server/NetPacksServer.cpp +++ b/server/NetPacksServer.cpp @@ -192,19 +192,19 @@ void ApplyGhNetPackVisitor::visitTradeOnMarketplace(TradeOnMarketplace & pack) break; case EMarketMode::RESOURCE_PLAYER: for(int i = 0; i < pack.r1.size(); ++i) - result &= gh.sendResources(pack.val[i], player, static_cast(pack.r1[i]), PlayerColor(pack.r2[i])); + result &= gh.sendResources(pack.val[i], player, GameResID(pack.r1[i]), PlayerColor(pack.r2[i])); break; case EMarketMode::CREATURE_RESOURCE: for(int i = 0; i < pack.r1.size(); ++i) - result &= gh.sellCreatures(pack.val[i], m, hero, SlotID(pack.r1[i]), static_cast(pack.r2[i])); + result &= gh.sellCreatures(pack.val[i], m, hero, SlotID(pack.r1[i]), GameResID(pack.r2[i])); break; case EMarketMode::RESOURCE_ARTIFACT: for(int i = 0; i < pack.r1.size(); ++i) - result &= gh.buyArtifact(m, hero, static_cast(pack.r1[i]), ArtifactID(pack.r2[i])); + result &= gh.buyArtifact(m, hero, GameResID(pack.r1[i]), ArtifactID(pack.r2[i])); break; case EMarketMode::ARTIFACT_RESOURCE: for(int i = 0; i < pack.r1.size(); ++i) - result &= gh.sellArtifact(m, hero, ArtifactInstanceID(pack.r1[i]), static_cast(pack.r2[i])); + result &= gh.sellArtifact(m, hero, ArtifactInstanceID(pack.r1[i]), GameResID(pack.r2[i])); break; case EMarketMode::CREATURE_UNDEAD: for(int i = 0; i < pack.r1.size(); ++i) diff --git a/test/entity/CCreatureTest.cpp b/test/entity/CCreatureTest.cpp index ed186452f..8a0803891 100644 --- a/test/entity/CCreatureTest.cpp +++ b/test/entity/CCreatureTest.cpp @@ -70,7 +70,7 @@ TEST_F(CCreatureTest, JsonUpdate) subject->updateFrom(data); - EXPECT_EQ(subject->getCost(Res::GOLD), 750); + EXPECT_EQ(subject->getRecruitCost(EGameResID::GOLD), 750); EXPECT_EQ(subject->getBaseAttack(), 17); EXPECT_EQ(subject->getAttack(false), 17); EXPECT_EQ(subject->getAttack(true), 17); diff --git a/test/erm/ERM_MA.cpp b/test/erm/ERM_MA.cpp index fdceb2db4..8762e0ace 100644 --- a/test/erm/ERM_MA.cpp +++ b/test/erm/ERM_MA.cpp @@ -96,7 +96,7 @@ TEST_F(ERM_MA, Example) std::shared_ptr added = std::make_shared(Bonus::PERMANENT, Bonus::NO_MELEE_PENALTY, Bonus::CREATURE_ABILITY, 0, 0); - EXPECT_CALL(oldCreature, getCost(Eq(6))).WillOnce(Return(COST)); + EXPECT_CALL(oldCreature, getRecruitCost(Eq(6))).WillOnce(Return(COST)); EXPECT_CALL(oldCreature, getBaseAttack()).WillOnce(Return(ATTACK)); EXPECT_CALL(oldCreature, getBaseDefense()).WillOnce(Return(DEFENSE)); EXPECT_CALL(oldCreature, getBaseHitPoints()).WillOnce(Return(HIT_POINTS)); @@ -115,7 +115,7 @@ TEST_F(ERM_MA, Example) EXPECT_CALL(oldCreature, isDoubleWide()).WillRepeatedly(Return(false)); - EXPECT_CALL(oldCreature, accessBonuses()).Times(AtLeast(1)).WillRepeatedly(Return(&creatureBonuses)); + EXPECT_CALL(oldCreature, getBonusBearer()).Times(AtLeast(1)).WillRepeatedly(Return(&creatureBonuses)); EXPECT_CALL(serverMock, apply(Matcher(_))).Times(AtLeast(1)).WillRepeatedly(Invoke(this, &ERM_MA::onCommit)); @@ -216,7 +216,7 @@ TEST_F(ERM_MA, Bonuses) EXPECT_CALL(oldCreature, isDoubleWide()).WillRepeatedly(Return(false)); - EXPECT_CALL(oldCreature, accessBonuses()).Times(AtLeast(1)).WillRepeatedly(Return(&creatureBonuses)); + EXPECT_CALL(oldCreature, getBonusBearer()).Times(AtLeast(1)).WillRepeatedly(Return(&creatureBonuses)); EXPECT_CALL(serverMock, apply(Matcher(_))).WillOnce(Invoke(this, &ERM_MA::onCommit)); @@ -272,7 +272,7 @@ TEST_F(ERM_MA, BonusesNoChanges) creatureBonuses.addNewBonus(std::make_shared(Bonus::PERMANENT, Bonus::UNDEAD, Bonus::CREATURE_ABILITY, 0, 0)); EXPECT_CALL(oldCreature, isDoubleWide()).WillRepeatedly(Return(false)); - EXPECT_CALL(oldCreature, accessBonuses()).Times(AtLeast(1)).WillRepeatedly(Return(&creatureBonuses)); + EXPECT_CALL(oldCreature, getBonusBearer()).Times(AtLeast(1)).WillRepeatedly(Return(&creatureBonuses)); EXPECT_CALL(serverMock, apply(Matcher(_))).Times(0); std::stringstream source; diff --git a/test/game/CGameStateTest.cpp b/test/game/CGameStateTest.cpp index 67d7d49d8..f4e77e847 100644 --- a/test/game/CGameStateTest.cpp +++ b/test/game/CGameStateTest.cpp @@ -263,9 +263,9 @@ TEST_F(CGameStateTest, issue2765) for(const CStack * s : gameState->curB->stacks) { - if(s->type->idNumber == CreatureID::BALLISTA && s->unitSide() == BattleSide::DEFENDER) + if(s->type->getId() == CreatureID::BALLISTA && s->unitSide() == BattleSide::DEFENDER) def = s; - else if(s->type->idNumber == CreatureID(69) && s->unitSide() == BattleSide::ATTACKER) + else if(s->type->getId() == CreatureID(69) && s->unitSide() == BattleSide::ATTACKER) att = s; } ASSERT_NE(att, nullptr); diff --git a/test/mock/mock_Creature.h b/test/mock/mock_Creature.h index 030b1a92d..c3b3d4572 100644 --- a/test/mock/mock_Creature.h +++ b/test/mock/mock_Creature.h @@ -22,7 +22,7 @@ public: MOCK_CONST_METHOD0(getJsonKey, const std::string &()); MOCK_CONST_METHOD0(getName, const std::string &()); MOCK_CONST_METHOD0(getId, CreatureID()); - MOCK_CONST_METHOD0(accessBonuses, const IBonusBearer *()); + MOCK_CONST_METHOD0(getBonusBearer, const IBonusBearer *()); MOCK_CONST_METHOD1(registerIcons, void(const IconRegistar &)); MOCK_CONST_METHOD0(getPluralName, const std::string &()); diff --git a/test/mock/mock_IGameCallback.h b/test/mock/mock_IGameCallback.h index 8f09d6c33..669bbbd13 100644 --- a/test/mock/mock_IGameCallback.h +++ b/test/mock/mock_IGameCallback.h @@ -48,7 +48,7 @@ public: void showGarrisonDialog(ObjectInstanceID upobj, ObjectInstanceID hid, bool removableUnits) override {} //cb will be called when player closes garrison window void showTeleportDialog(TeleportDialog *iw) override {} void showThievesGuildWindow(PlayerColor player, ObjectInstanceID requestingObjId) override {} - void giveResource(PlayerColor player, Res::ERes which, int val) override {} + void giveResource(PlayerColor player, EGameResID which, int val) override {} void giveResources(PlayerColor player, TResources resources) override {} void giveCreatures(const CArmedInstance *objid, const CGHeroInstance * h, const CCreatureSet &creatures, bool remove) override {} diff --git a/test/mock/mock_battle_IBattleState.h b/test/mock/mock_battle_IBattleState.h index 779c12773..895ba626f 100644 --- a/test/mock/mock_battle_IBattleState.h +++ b/test/mock/mock_battle_IBattleState.h @@ -31,7 +31,7 @@ public: MOCK_CONST_METHOD1(getEnchanterCounter, int32_t(ui8)); MOCK_CONST_METHOD0(getTacticDist, ui8()); MOCK_CONST_METHOD0(getTacticsSide, ui8()); - MOCK_CONST_METHOD0(asBearer, const IBonusBearer *()); + MOCK_CONST_METHOD0(getBonusBearer, const IBonusBearer *()); MOCK_CONST_METHOD0(nextUnitId, uint32_t()); MOCK_CONST_METHOD3(getActualDamage, int64_t(const TDmgRange &, int32_t, vstd::RNG &)); diff --git a/test/vcai/ResurceManagerTest.cpp b/test/vcai/ResurceManagerTest.cpp index b0d7afc93..df6fd90be 100644 --- a/test/vcai/ResurceManagerTest.cpp +++ b/test/vcai/ResurceManagerTest.cpp @@ -153,7 +153,7 @@ TEST_F(ResourceManagerTest, queueOrder) goal = rm->whatToDo(price, buildNotSoExtra); EXPECT_NE(goal->bid, 7); EXPECT_EQ(goal->goalType, Goals::COLLECT_RES) << "We can't afford this goal, need to collect resources"; - EXPECT_EQ(goal->resID, Res::GOLD) << "We need to collect gold"; + EXPECT_EQ(goal->resID, EGameResID::GOLD) << "We need to collect gold"; goal = rm->whatToDo(); EXPECT_NE(goal->goalType, Goals::COLLECT_RES); @@ -165,7 +165,7 @@ TEST_F(ResourceManagerTest, updateGoalImplemented) ASSERT_FALSE(rm->hasTasksLeft()); TResources res; - res[Res::GOLD] = 12345; + res[EGameResID::GOLD] = 12345; buildThis->setpriority(1); buildThis->bid = 666; @@ -208,14 +208,14 @@ TEST_F(ResourceManagerTest, freeResources) .WillByDefault(Return(TResources(-1, 0, -13, -38763, -93764, -464, -12, -98765))); auto res = rm->freeResources(); - ASSERT_GE(res[Res::WOOD], 0); - ASSERT_GE(res[Res::MERCURY], 0); - ASSERT_GE(res[Res::ORE], 0); - ASSERT_GE(res[Res::SULFUR], 0); - ASSERT_GE(res[Res::CRYSTAL], 0); - ASSERT_GE(res[Res::GEMS], 0); - ASSERT_GE(res[Res::GOLD], 0); - ASSERT_GE(res[Res::MITHRIL], 0); + ASSERT_GE(res[EGameResID::WOOD], 0); + ASSERT_GE(res[EGameResID::MERCURY], 0); + ASSERT_GE(res[EGameResID::ORE], 0); + ASSERT_GE(res[EGameResID::SULFUR], 0); + ASSERT_GE(res[EGameResID::CRYSTAL], 0); + ASSERT_GE(res[EGameResID::GEMS], 0); + ASSERT_GE(res[EGameResID::GOLD], 0); + ASSERT_GE(res[EGameResID::MITHRIL], 0); } TEST_F(ResourceManagerTest, freeResourcesWithManyGoals) @@ -231,13 +231,13 @@ TEST_F(ResourceManagerTest, freeResourcesWithManyGoals) ASSERT_EQ(rm->freeResources(), TResources(15, 2, 15, 6, 6, 6, 2000, 0)); rm->reserveResoures(TResources(0, 0, 0, 0, 0, 0, 2500), recruitHero); auto res = rm->freeResources(); - EXPECT_EQ(res[Res::GOLD], 0) << "We should have 0 gold left"; + EXPECT_EQ(res[EGameResID::GOLD], 0) << "We should have 0 gold left"; ON_CALL(gcm, getResourceAmount()) .WillByDefault(Return(TResources(20, 10, 20, 10, 10, 10, 30000, 0))); //+10000 gold res = rm->freeResources(); - EXPECT_EQ(res[Res::GOLD], 9500) << "We should have extra savings now"; + EXPECT_EQ(res[EGameResID::GOLD], 9500) << "We should have extra savings now"; } TEST_F(ResourceManagerTest, freeGold)