mirror of
https://github.com/vcmi/vcmi.git
synced 2025-11-25 22:42:04 +02:00
more cc renaming; BuildingID get level index and upgrades; Creatures renaming
This commit is contained in:
@@ -211,8 +211,8 @@ BuildingInfo BuildAnalyzer::getBuildingOrPrerequisite(
|
||||
|
||||
if(toBuild.isDwelling())
|
||||
{
|
||||
creatureLevel = BuildingID::getLevelFromDwelling(toBuild);
|
||||
creatureUpgrade = BuildingID::getUpgradedFromDwelling(toBuild);
|
||||
creatureLevel = BuildingID::getLevelIndexFromDwelling(toBuild);
|
||||
creatureUpgrade = BuildingID::getUpgradeNoFromDwelling(toBuild);
|
||||
}
|
||||
else if(toBuild == BuildingID::HORDE_1 || toBuild == BuildingID::HORDE_1_UPGR)
|
||||
{
|
||||
|
||||
@@ -119,13 +119,13 @@ std::vector<SlotInfo>::iterator ArmyManager::getBestUnitForScout(std::vector<Slo
|
||||
for (const auto & unit : army)
|
||||
totalPower += unit.power;
|
||||
|
||||
int baseMovementCost = cb->getSettings().getInteger(EGameSettings::HEROES_MOVEMENT_COST_BASE);
|
||||
int baseMovementCost = cpsic->getSettings().getInteger(EGameSettings::HEROES_MOVEMENT_COST_BASE);
|
||||
bool terrainHasPenalty = armyTerrain.hasValue() && armyTerrain.toEntity(LIBRARY)->moveCost != baseMovementCost;
|
||||
|
||||
// arbitrary threshold - don't give scout more than specified part of total AI value of our army
|
||||
uint64_t maxUnitValue = totalPower / 100;
|
||||
|
||||
const auto & movementPointsLimits = cb->getSettings().getVector(EGameSettings::HEROES_MOVEMENT_POINTS_LAND);
|
||||
const auto & movementPointsLimits = cpsic->getSettings().getVector(EGameSettings::HEROES_MOVEMENT_POINTS_LAND);
|
||||
|
||||
auto fastest = boost::min_element(army, [&](const SlotInfo & left, const SlotInfo & right) -> bool
|
||||
{
|
||||
@@ -231,9 +231,9 @@ std::vector<SlotInfo> ArmyManager::getBestArmy(const IBonusBearer * armyCarrier,
|
||||
auto morale = slot.second->moraleVal();
|
||||
auto multiplier = 1.0f;
|
||||
|
||||
const auto & badMoraleChance = cb->getSettings().getVector(EGameSettings::COMBAT_BAD_MORALE_CHANCE);
|
||||
const auto & highMoraleChance = cb->getSettings().getVector(EGameSettings::COMBAT_GOOD_MORALE_CHANCE);
|
||||
int moraleDiceSize = cb->getSettings().getInteger(EGameSettings::COMBAT_MORALE_DICE_SIZE);
|
||||
const auto & badMoraleChance = cpsic->getSettings().getVector(EGameSettings::COMBAT_BAD_MORALE_CHANCE);
|
||||
const auto & highMoraleChance = cpsic->getSettings().getVector(EGameSettings::COMBAT_GOOD_MORALE_CHANCE);
|
||||
int moraleDiceSize = cpsic->getSettings().getInteger(EGameSettings::COMBAT_MORALE_DICE_SIZE);
|
||||
|
||||
if(morale < 0 && !badMoraleChance.empty())
|
||||
{
|
||||
@@ -347,7 +347,7 @@ std::vector<creInfo> ArmyManager::getArmyAvailableToBuy(
|
||||
{
|
||||
std::vector<creInfo> creaturesInDwellings;
|
||||
int freeHeroSlots = GameConstants::ARMY_SIZE - hero->stacksCount();
|
||||
bool countGrowth = (cb->getDate(Date::DAY_OF_WEEK) + turn) > 7;
|
||||
bool countGrowth = (cpsic->getDate(Date::DAY_OF_WEEK) + turn) > 7;
|
||||
|
||||
const CGTownInstance * town = dwelling->ID == Obj::TOWN
|
||||
? dynamic_cast<const CGTownInstance *>(dwelling)
|
||||
@@ -478,8 +478,8 @@ void ArmyManager::update()
|
||||
logAi->trace("Start analysing army");
|
||||
|
||||
std::vector<const CCreatureSet *> total;
|
||||
auto heroes = cb->getHeroesInfo();
|
||||
auto towns = cb->getTownsInfo();
|
||||
auto heroes = cpsic->getHeroesInfo();
|
||||
auto towns = cpsic->getTownsInfo();
|
||||
|
||||
std::copy(heroes.begin(), heroes.end(), std::back_inserter(total));
|
||||
std::copy(towns.begin(), towns.end(), std::back_inserter(total));
|
||||
|
||||
@@ -82,12 +82,12 @@ class StackUpgradeInfo;
|
||||
class DLL_EXPORT ArmyManager : public IArmyManager
|
||||
{
|
||||
private:
|
||||
CPlayerSpecificInfoCallback * cb; //this is enough, but we downcast from CCallback
|
||||
CPlayerSpecificInfoCallback * cpsic; //this is enough, but we downcast from CCallback
|
||||
const Nullkiller * aiNk;
|
||||
std::map<CreatureID, SlotInfo> totalArmy;
|
||||
|
||||
public:
|
||||
ArmyManager(CPlayerSpecificInfoCallback * CB, const Nullkiller * ai): cb(CB), aiNk(ai) {}
|
||||
ArmyManager(CPlayerSpecificInfoCallback * cpsic, const Nullkiller * ai): cpsic(cpsic), aiNk(ai) {}
|
||||
void update() override;
|
||||
|
||||
ui64 howManyReinforcementsCanBuy(const CCreatureSet * target, const CGDwelling * source) const override;
|
||||
|
||||
@@ -19,16 +19,14 @@ namespace NK2AI
|
||||
|
||||
TResources BuildAnalyzer::getResourcesRequiredNow() const
|
||||
{
|
||||
auto resourcesAvailable = aiNk->getFreeResources();
|
||||
auto result = withoutGold(armyCost) + requiredResources - resourcesAvailable;
|
||||
auto result = withoutGold(armyCost) + requiredResources - aiNk->getFreeResources();
|
||||
result.positive();
|
||||
return result;
|
||||
}
|
||||
|
||||
TResources BuildAnalyzer::getTotalResourcesRequired() const
|
||||
{
|
||||
auto resourcesAvailable = aiNk->getFreeResources();
|
||||
auto result = totalDevelopmentCost + withoutGold(armyCost) - resourcesAvailable;
|
||||
auto result = totalDevelopmentCost + withoutGold(armyCost) - aiNk->getFreeResources();
|
||||
result.positive();
|
||||
return result;
|
||||
}
|
||||
@@ -57,7 +55,7 @@ void BuildAnalyzer::update()
|
||||
developmentInfos.push_back(TownDevelopmentInfo(town));
|
||||
TownDevelopmentInfo & tdi = developmentInfos.back();
|
||||
|
||||
updateCreatureBuildings(tdi, aiNk->armyManager, aiNk->cc);
|
||||
updateDwellings(tdi, aiNk->armyManager, aiNk->cc);
|
||||
updateOtherBuildings(tdi, aiNk->armyManager, aiNk->cc);
|
||||
requiredResources += tdi.requiredResources;
|
||||
totalDevelopmentCost += tdi.townDevelopmentCost;
|
||||
@@ -110,7 +108,7 @@ bool BuildAnalyzer::isBuilt(FactionID alignment, BuildingID bid) const
|
||||
return false;
|
||||
}
|
||||
|
||||
void TownDevelopmentInfo::addExistingDwelling(const BuildingInfo & bi)
|
||||
void TownDevelopmentInfo::addBuildingBuilt(const BuildingInfo & bi)
|
||||
{
|
||||
armyCost += bi.armyCost;
|
||||
armyStrength += bi.armyStrength;
|
||||
@@ -149,43 +147,43 @@ BuildingInfo::BuildingInfo(
|
||||
|
||||
if(creature)
|
||||
{
|
||||
creatureGrows = creature->getGrowth();
|
||||
creatureGrowth = creature->getGrowth();
|
||||
creatureID = creature->getId();
|
||||
baseCreatureID = baseCreature;
|
||||
creatureCost = creature->getFullRecruitCost();
|
||||
creatureUnitCost = creature->getFullRecruitCost();
|
||||
creatureLevel = creature->getLevel();
|
||||
|
||||
if(isBuilt)
|
||||
{
|
||||
creatureGrows = town->creatureGrowth(creatureLevel - 1);
|
||||
creatureGrowth = town->creatureGrowth(creatureLevel - 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(id.isDwelling())
|
||||
{
|
||||
creatureGrows = creature->getGrowth();
|
||||
creatureGrowth = creature->getGrowth();
|
||||
|
||||
if(town->hasBuilt(BuildingID::CASTLE))
|
||||
creatureGrows *= 2;
|
||||
creatureGrowth *= 2;
|
||||
else if(town->hasBuilt(BuildingID::CITADEL))
|
||||
creatureGrows += creatureGrows / 2;
|
||||
creatureGrowth += creatureGrowth / 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
creatureGrows = creature->getHorde();
|
||||
creatureGrowth = creature->getHorde();
|
||||
}
|
||||
}
|
||||
|
||||
armyStrength = armyManager->evaluateStackPower(creature, creatureGrows);
|
||||
armyCost = creatureCost * creatureGrows;
|
||||
armyStrength = armyManager->evaluateStackPower(creature, creatureGrowth);
|
||||
armyCost = creatureUnitCost * creatureGrowth;
|
||||
}
|
||||
}
|
||||
|
||||
std::string BuildingInfo::toString() const
|
||||
{
|
||||
return name + ", cost: " + buildCost.toString()
|
||||
+ ", creature: " + std::to_string(creatureGrows) + " x " + std::to_string(creatureLevel)
|
||||
+ " x " + creatureCost.toString()
|
||||
+ ", creature: " + std::to_string(creatureGrowth) + " x " + std::to_string(creatureLevel)
|
||||
+ " x " + creatureUnitCost.toString()
|
||||
+ ", daily: " + dailyIncome.toString();
|
||||
}
|
||||
|
||||
@@ -218,7 +216,7 @@ TResources BuildAnalyzer::calculateDailyIncome(const std::vector<const CGObjectI
|
||||
return result;
|
||||
}
|
||||
|
||||
void BuildAnalyzer::updateCreatureBuildings(TownDevelopmentInfo & developmentInfo, std::unique_ptr<ArmyManager> & armyManager, std::shared_ptr<CCallback> & cb)
|
||||
void BuildAnalyzer::updateDwellings(TownDevelopmentInfo & developmentInfo, std::unique_ptr<ArmyManager> & armyManager, std::shared_ptr<CCallback> & cc)
|
||||
{
|
||||
for(int level = 0; level < developmentInfo.town->getTown()->creatures.size(); level++)
|
||||
{
|
||||
@@ -237,8 +235,8 @@ void BuildAnalyzer::updateCreatureBuildings(TownDevelopmentInfo & developmentInf
|
||||
if (!developmentInfo.town->hasBuilt(buildID))
|
||||
continue;
|
||||
|
||||
const auto & info = getBuildingOrPrerequisite(developmentInfo.town, buildID, armyManager, cb);
|
||||
developmentInfo.addExistingDwelling(info);
|
||||
const auto & info = getBuildingOrPrerequisite(developmentInfo.town, buildID, armyManager, cc);
|
||||
developmentInfo.addBuildingBuilt(info);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -248,7 +246,7 @@ void BuildAnalyzer::updateCreatureBuildings(TownDevelopmentInfo & developmentInf
|
||||
if (developmentInfo.town->hasBuilt(buildID))
|
||||
continue;
|
||||
|
||||
const auto & info = getBuildingOrPrerequisite(developmentInfo.town, buildID, armyManager, cb);
|
||||
const auto & info = getBuildingOrPrerequisite(developmentInfo.town, buildID, armyManager, cc);
|
||||
if (info.isBuildable || info.isMissingResources)
|
||||
developmentInfo.addBuildingToBuild(info);
|
||||
}
|
||||
@@ -257,7 +255,7 @@ void BuildAnalyzer::updateCreatureBuildings(TownDevelopmentInfo & developmentInf
|
||||
|
||||
void BuildAnalyzer::updateOtherBuildings(TownDevelopmentInfo & developmentInfo,
|
||||
std::unique_ptr<ArmyManager> & armyManager,
|
||||
std::shared_ptr<CCallback> & cb)
|
||||
std::shared_ptr<CCallback> & cc)
|
||||
{
|
||||
logAi->trace("Checking other buildings");
|
||||
|
||||
@@ -266,7 +264,7 @@ void BuildAnalyzer::updateOtherBuildings(TownDevelopmentInfo & developmentInfo,
|
||||
{BuildingID::MAGES_GUILD_3, BuildingID::MAGES_GUILD_5}
|
||||
};
|
||||
|
||||
if(developmentInfo.built.size() >= 2 && cb->getDate(Date::DAY_OF_WEEK) > 4)
|
||||
if(developmentInfo.built.size() >= 2 && cc->getDate(Date::DAY_OF_WEEK) > 4)
|
||||
{
|
||||
otherBuildings.push_back({BuildingID::HORDE_1});
|
||||
otherBuildings.push_back({BuildingID::HORDE_2});
|
||||
@@ -286,7 +284,7 @@ void BuildAnalyzer::updateOtherBuildings(TownDevelopmentInfo & developmentInfo,
|
||||
{
|
||||
if(!developmentInfo.town->hasBuilt(buildingID) && developmentInfo.town->getTown()->buildings.count(buildingID))
|
||||
{
|
||||
developmentInfo.addBuildingToBuild(getBuildingOrPrerequisite(developmentInfo.town, buildingID, armyManager, cb));
|
||||
developmentInfo.addBuildingToBuild(getBuildingOrPrerequisite(developmentInfo.town, buildingID, armyManager, cc));
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -295,40 +293,40 @@ void BuildAnalyzer::updateOtherBuildings(TownDevelopmentInfo & developmentInfo,
|
||||
|
||||
BuildingInfo BuildAnalyzer::getBuildingOrPrerequisite(
|
||||
const CGTownInstance * town,
|
||||
BuildingID toBuild,
|
||||
BuildingID b,
|
||||
std::unique_ptr<ArmyManager> & armyManager,
|
||||
std::shared_ptr<CCallback> & cb,
|
||||
std::shared_ptr<CCallback> & cc,
|
||||
bool excludeDwellingDependencies)
|
||||
{
|
||||
BuildingID building = toBuild;
|
||||
// TODO: Mircea: Remove redundant variable
|
||||
BuildingID building = b;
|
||||
const auto * townInfo = town->getTown();
|
||||
|
||||
const auto & buildPtr = townInfo->buildings.at(building);
|
||||
const CCreature * creature = nullptr;
|
||||
CreatureID baseCreatureID;
|
||||
|
||||
int creatureLevel = -1;
|
||||
int creatureUpgrade = 0;
|
||||
int creatureLevelIndex = -1;
|
||||
int creatureUpgradeNo = 0;
|
||||
|
||||
if(toBuild.isDwelling())
|
||||
if(b.isDwelling())
|
||||
{
|
||||
creatureLevel = BuildingID::getLevelFromDwelling(toBuild);
|
||||
creatureUpgrade = BuildingID::getUpgradedFromDwelling(toBuild);
|
||||
creatureLevelIndex = BuildingID::getLevelIndexFromDwelling(b);
|
||||
creatureUpgradeNo = BuildingID::getUpgradeNoFromDwelling(b);
|
||||
}
|
||||
else if(toBuild == BuildingID::HORDE_1 || toBuild == BuildingID::HORDE_1_UPGR)
|
||||
else if(b == BuildingID::HORDE_1 || b == BuildingID::HORDE_1_UPGR)
|
||||
{
|
||||
creatureLevel = townInfo->hordeLvl.at(0);
|
||||
creatureLevelIndex = townInfo->hordeLvl.at(0);
|
||||
}
|
||||
else if(toBuild == BuildingID::HORDE_2 || toBuild == BuildingID::HORDE_2_UPGR)
|
||||
else if(b == BuildingID::HORDE_2 || b == BuildingID::HORDE_2_UPGR)
|
||||
{
|
||||
creatureLevel = townInfo->hordeLvl.at(1);
|
||||
creatureLevelIndex = townInfo->hordeLvl.at(1);
|
||||
}
|
||||
|
||||
if(creatureLevel >= 0)
|
||||
if(creatureLevelIndex >= 0)
|
||||
{
|
||||
auto creatures = townInfo->creatures.at(creatureLevel);
|
||||
auto creatureID = creatures.size() > creatureUpgrade
|
||||
? creatures.at(creatureUpgrade)
|
||||
auto creatures = townInfo->creatures.at(creatureLevelIndex);
|
||||
auto creatureID = creatures.size() > creatureUpgradeNo
|
||||
? creatures.at(creatureUpgradeNo)
|
||||
: creatures.front();
|
||||
|
||||
baseCreatureID = creatures.front();
|
||||
@@ -340,14 +338,14 @@ BuildingInfo BuildAnalyzer::getBuildingOrPrerequisite(
|
||||
//logAi->trace("checking %s buildInfo %s", info.name, info.toString());
|
||||
|
||||
int highestFort = 0;
|
||||
for (const auto * ti : cb->getTownsInfo())
|
||||
for (const auto * ti : cc->getTownsInfo())
|
||||
{
|
||||
highestFort = std::max(highestFort, static_cast<int>(ti->fortLevel()));
|
||||
}
|
||||
|
||||
if(!town->hasBuilt(building))
|
||||
{
|
||||
auto canBuild = cb->canBuildStructure(town, building);
|
||||
auto canBuild = cc->canBuildStructure(town, building);
|
||||
|
||||
if(canBuild == EBuildingState::ALLOWED)
|
||||
{
|
||||
@@ -374,25 +372,26 @@ BuildingInfo BuildAnalyzer::getBuildingOrPrerequisite(
|
||||
if(vstd::contains_if(missingBuildings, otherDwelling))
|
||||
{
|
||||
#if NKAI_TRACE_LEVEL >= 1
|
||||
logAi->trace("Can't build %d. Needs other dwelling %d", toBuild.getNum(), missingBuildings.front().getNum());
|
||||
logAi->trace("Can't build %d. Needs other dwelling %d", b.getNum(), missingBuildings.front().getNum());
|
||||
#endif
|
||||
}
|
||||
else if(missingBuildings[0] != toBuild)
|
||||
else if(missingBuildings[0] != b)
|
||||
{
|
||||
#if NKAI_TRACE_LEVEL >= 1
|
||||
logAi->trace("Can't build %d. Needs %d", toBuild.getNum(), missingBuildings[0].num);
|
||||
logAi->trace("Can't build %d. Needs %d", b.getNum(), missingBuildings[0].num);
|
||||
#endif
|
||||
BuildingInfo prerequisite = getBuildingOrPrerequisite(town, missingBuildings[0], armyManager, cb, excludeDwellingDependencies);
|
||||
BuildingInfo prerequisite = getBuildingOrPrerequisite(town, missingBuildings[0], armyManager, cc, excludeDwellingDependencies);
|
||||
|
||||
prerequisite.buildCostWithPrerequisites += info.buildCost;
|
||||
prerequisite.creatureCost = info.creatureCost;
|
||||
prerequisite.creatureGrows = info.creatureGrows;
|
||||
prerequisite.creatureUnitCost = info.creatureUnitCost;
|
||||
prerequisite.creatureGrowth = info.creatureGrowth;
|
||||
prerequisite.creatureLevel = info.creatureLevel;
|
||||
prerequisite.creatureID = info.creatureID;
|
||||
prerequisite.baseCreatureID = info.baseCreatureID;
|
||||
prerequisite.prerequisitesCount++;
|
||||
prerequisite.armyCost = info.armyCost;
|
||||
prerequisite.armyStrength = info.armyStrength;
|
||||
|
||||
bool haveSameOrBetterFort = false;
|
||||
if (prerequisite.id == BuildingID::FORT && highestFort >= CGTownInstance::EFortLevel::FORT)
|
||||
haveSameOrBetterFort = true;
|
||||
@@ -423,7 +422,7 @@ BuildingInfo BuildAnalyzer::getBuildingOrPrerequisite(
|
||||
else
|
||||
{
|
||||
#if NKAI_TRACE_LEVEL >= 1
|
||||
logAi->trace("Dwelling %d exists", toBuild.getNum());
|
||||
logAi->trace("Dwelling %d exists", b.getNum());
|
||||
#endif
|
||||
info.isBuilt = true;
|
||||
}
|
||||
|
||||
@@ -24,15 +24,15 @@ public:
|
||||
BuildingID id = BuildingID::NONE;
|
||||
TResources buildCost;
|
||||
TResources buildCostWithPrerequisites;
|
||||
int creatureGrows = 0;
|
||||
uint8_t creatureLevel = 0;
|
||||
TResources creatureCost;
|
||||
int creatureGrowth = 0;
|
||||
uint8_t creatureLevel = 0; /// @link CCreature::level
|
||||
TResources creatureUnitCost;
|
||||
CreatureID creatureID = CreatureID::NONE;
|
||||
CreatureID baseCreatureID = CreatureID::NONE;
|
||||
TResources dailyIncome;
|
||||
uint8_t prerequisitesCount = 0;
|
||||
uint64_t armyStrength = 0;
|
||||
TResources armyCost;
|
||||
TResources armyCost; // creatureCost * creatureGrows
|
||||
std::string name;
|
||||
bool isBuilt = false;
|
||||
bool isBuildable = false;
|
||||
@@ -64,8 +64,8 @@ public:
|
||||
TownDevelopmentInfo(const CGTownInstance * town) : town(town) {}
|
||||
TownDevelopmentInfo() : TownDevelopmentInfo(nullptr) {}
|
||||
|
||||
void addBuildingToBuild(const BuildingInfo & building);
|
||||
void addExistingDwelling(const BuildingInfo & bi);
|
||||
void addBuildingToBuild(const BuildingInfo & bi);
|
||||
void addBuildingBuilt(const BuildingInfo & bi);
|
||||
};
|
||||
|
||||
class DLL_EXPORT BuildAnalyzer
|
||||
@@ -94,13 +94,13 @@ public:
|
||||
|
||||
static float calculateGoldPressure(TResource lockedGold, float armyCostGold, float economyDevelopmentCost, float freeGold, float dailyIncomeGold);
|
||||
static TResources calculateDailyIncome(const std::vector<const CGObjectInstance *> & objects, const std::vector<const CGTownInstance *> & townInfos);
|
||||
static void updateCreatureBuildings(TownDevelopmentInfo& developmentInfo, std::unique_ptr<ArmyManager>& armyManager, std::shared_ptr<CCallback>& cb);
|
||||
static void updateOtherBuildings(TownDevelopmentInfo& developmentInfo, std::unique_ptr<ArmyManager>& armyManager, std::shared_ptr<CCallback>& cb);
|
||||
static void updateDwellings(TownDevelopmentInfo& developmentInfo, std::unique_ptr<ArmyManager>& armyManager, std::shared_ptr<CCallback>& cc);
|
||||
static void updateOtherBuildings(TownDevelopmentInfo& developmentInfo, std::unique_ptr<ArmyManager>& armyManager, std::shared_ptr<CCallback>& cc);
|
||||
static BuildingInfo getBuildingOrPrerequisite(
|
||||
const CGTownInstance* town,
|
||||
BuildingID toBuild,
|
||||
BuildingID b,
|
||||
std::unique_ptr<ArmyManager> & armyManager,
|
||||
std::shared_ptr<CCallback> & cb,
|
||||
std::shared_ptr<CCallback> & cc,
|
||||
bool excludeDwellingDependencies = true);
|
||||
static int32_t approximateInGold(const TResources & res);
|
||||
static TResources withoutGold(TResources other);
|
||||
|
||||
@@ -70,7 +70,7 @@ void DangerHitMapAnalyzer::updateHitMap()
|
||||
hitMapUpToDate = true;
|
||||
auto start = std::chrono::high_resolution_clock::now();
|
||||
|
||||
auto cb = aiNk->cc.get();
|
||||
auto cc = aiNk->cc.get();
|
||||
auto mapSize = aiNk->cc->getMapSize();
|
||||
|
||||
if(hitMap.shape()[0] != mapSize.x || hitMap.shape()[1] != mapSize.y || hitMap.shape()[2] != mapSize.z)
|
||||
@@ -98,7 +98,7 @@ void DangerHitMapAnalyzer::updateHitMap()
|
||||
}
|
||||
}
|
||||
|
||||
auto ourTowns = cb->getTownsInfo();
|
||||
auto ourTowns = cc->getTownsInfo();
|
||||
|
||||
for(auto town : ourTowns)
|
||||
{
|
||||
@@ -158,7 +158,7 @@ void DangerHitMapAnalyzer::updateHitMap()
|
||||
node.fastestDanger = newThreat;
|
||||
}
|
||||
|
||||
auto objects = cb->getVisitableObjs(pos, false);
|
||||
auto objects = cc->getVisitableObjs(pos, false);
|
||||
|
||||
for(auto obj : objects)
|
||||
{
|
||||
@@ -183,7 +183,7 @@ void DangerHitMapAnalyzer::updateHitMap()
|
||||
|
||||
if(newThreat.turn == 0)
|
||||
{
|
||||
if(cb->getPlayerRelations(obj->tempOwner, aiNk->playerID) != PlayerRelations::ENEMIES)
|
||||
if(cc->getPlayerRelations(obj->tempOwner, aiNk->playerID) != PlayerRelations::ENEMIES)
|
||||
enemyHeroAccessibleObjects.emplace_back(path.targetHero, obj);
|
||||
}
|
||||
}
|
||||
@@ -203,7 +203,7 @@ void DangerHitMapAnalyzer::calculateTileOwners()
|
||||
|
||||
tileOwnersUpToDate = true;
|
||||
|
||||
auto cb = aiNk->cc.get();
|
||||
auto * cc = aiNk->cc.get();
|
||||
auto mapSize = aiNk->cc->getMapSize();
|
||||
|
||||
if(hitMap.shape()[0] != mapSize.x || hitMap.shape()[1] != mapSize.y || hitMap.shape()[2] != mapSize.z)
|
||||
@@ -215,7 +215,7 @@ void DangerHitMapAnalyzer::calculateTileOwners()
|
||||
|
||||
auto addTownHero = [&](const CGTownInstance * town)
|
||||
{
|
||||
auto townHero = temporaryHeroes.emplace_back(std::make_unique<CGHeroInstance>(town->cb)).get();
|
||||
auto *townHero = temporaryHeroes.emplace_back(std::make_unique<CGHeroInstance>(town->cb)).get();
|
||||
GameRandomizer randomizer(*town->cb);
|
||||
auto visitablePos = town->visitablePos();
|
||||
|
||||
@@ -229,7 +229,7 @@ void DangerHitMapAnalyzer::calculateTileOwners()
|
||||
townHeroes[townHero] = HeroRole::MAIN;
|
||||
};
|
||||
|
||||
for(auto obj : aiNk->memory->visitableObjs)
|
||||
for(const auto *obj : aiNk->memory->visitableObjs)
|
||||
{
|
||||
if(obj && obj->ID == Obj::TOWN)
|
||||
{
|
||||
@@ -237,7 +237,7 @@ void DangerHitMapAnalyzer::calculateTileOwners()
|
||||
}
|
||||
}
|
||||
|
||||
for(auto town : cb->getTownsInfo())
|
||||
for(const auto *town : cc->getTownsInfo())
|
||||
{
|
||||
addTownHero(town);
|
||||
}
|
||||
@@ -259,7 +259,7 @@ void DangerHitMapAnalyzer::calculateTileOwners()
|
||||
if(!path.targetHero || path.getFirstBlockedAction())
|
||||
continue;
|
||||
|
||||
auto town = heroTownMap[path.targetHero];
|
||||
const auto *town = heroTownMap[path.targetHero];
|
||||
|
||||
if(town->getOwner() == aiNk->playerID)
|
||||
{
|
||||
@@ -305,7 +305,7 @@ const std::vector<HitMapInfo> & DangerHitMapAnalyzer::getTownThreats(const CGTow
|
||||
|
||||
PlayerColor DangerHitMapAnalyzer::getTileOwner(const int3 & tile) const
|
||||
{
|
||||
auto town = hitMap[tile.x][tile.y][tile.z].closestTown;
|
||||
const auto *town = hitMap[tile.x][tile.y][tile.z].closestTown;
|
||||
|
||||
return town ? town->getOwner() : PlayerColor::NEUTRAL;
|
||||
}
|
||||
@@ -342,7 +342,7 @@ std::set<const CGObjectInstance *> DangerHitMapAnalyzer::getOneTurnAccessibleObj
|
||||
{
|
||||
std::set<const CGObjectInstance *> result;
|
||||
|
||||
for(auto & obj : enemyHeroAccessibleObjects)
|
||||
for(const auto & obj : enemyHeroAccessibleObjects)
|
||||
{
|
||||
if(obj.hero == enemy)
|
||||
result.insert(obj.obj);
|
||||
|
||||
@@ -105,7 +105,7 @@ void HeroManager::update()
|
||||
logAi->trace("Start analysing our heroes");
|
||||
|
||||
std::map<const CGHeroInstance *, float> scores;
|
||||
auto myHeroes = cb->getHeroesInfo();
|
||||
auto myHeroes = cc->getHeroesInfo();
|
||||
|
||||
for(auto & hero : myHeroes)
|
||||
{
|
||||
@@ -118,10 +118,10 @@ void HeroManager::update()
|
||||
return scores.at(h1) > scores.at(h2);
|
||||
};
|
||||
|
||||
int globalMainCount = std::min(((int)myHeroes.size() + 2) / 3, cb->getMapSize().x / 50 + 1);
|
||||
int globalMainCount = std::min(((int)myHeroes.size() + 2) / 3, cc->getMapSize().x / 50 + 1);
|
||||
|
||||
//vstd::amin(globalMainCount, 1 + (cb->getTownsInfo().size() / 3));
|
||||
if(cb->getTownsInfo().size() < 4 && globalMainCount > 2)
|
||||
if(cc->getTownsInfo().size() < 4 && globalMainCount > 2)
|
||||
{
|
||||
globalMainCount = 2;
|
||||
}
|
||||
@@ -195,11 +195,12 @@ float HeroManager::evaluateHero(const CGHeroInstance * hero) const
|
||||
|
||||
bool HeroManager::heroCapReached(bool includeGarrisoned) const
|
||||
{
|
||||
int heroCount = cb->getHeroCount(ai->playerID, includeGarrisoned);
|
||||
int heroCount = cc->getHeroCount(aiNk->playerID, includeGarrisoned);
|
||||
int maxAllowed = 1 + cc->howManyTowns() * aiNk->settings->getMaxRoamingHeroes();
|
||||
|
||||
return heroCount >= ai->settings->getMaxRoamingHeroes()
|
||||
|| heroCount >= cb->getSettings().getInteger(EGameSettings::HEROES_PER_PLAYER_ON_MAP_CAP)
|
||||
|| heroCount >= cb->getSettings().getInteger(EGameSettings::HEROES_PER_PLAYER_TOTAL_CAP);
|
||||
return heroCount >= maxAllowed
|
||||
|| heroCount >= cc->getSettings().getInteger(EGameSettings::HEROES_PER_PLAYER_ON_MAP_CAP)
|
||||
|| heroCount >= cc->getSettings().getInteger(EGameSettings::HEROES_PER_PLAYER_TOTAL_CAP);
|
||||
}
|
||||
|
||||
float HeroManager::getFightingStrengthCached(const CGHeroInstance * hero) const
|
||||
@@ -256,13 +257,13 @@ bool HeroManager::canRecruitHero(const CGTownInstance * town) const
|
||||
if(!town || !townHasFreeTavern(town))
|
||||
return false;
|
||||
|
||||
if(cb->getResourceAmount(EGameResID::GOLD) < GameConstants::HERO_GOLD_COST)
|
||||
if(cc->getResourceAmount(EGameResID::GOLD) < GameConstants::HERO_GOLD_COST)
|
||||
return false;
|
||||
|
||||
if(heroCapReached())
|
||||
return false;
|
||||
|
||||
if(!cb->getAvailableHeroes(town).size())
|
||||
if(!cc->getAvailableHeroes(town).size())
|
||||
return false;
|
||||
|
||||
return true;
|
||||
@@ -270,7 +271,7 @@ bool HeroManager::canRecruitHero(const CGTownInstance * town) const
|
||||
|
||||
const CGTownInstance * HeroManager::findTownWithTavern() const
|
||||
{
|
||||
for(const CGTownInstance * t : cb->getTownsInfo())
|
||||
for(const CGTownInstance * t : cc->getTownsInfo())
|
||||
if(townHasFreeTavern(t))
|
||||
return t;
|
||||
|
||||
@@ -279,7 +280,7 @@ const CGTownInstance * HeroManager::findTownWithTavern() const
|
||||
|
||||
const CGHeroInstance * HeroManager::findHeroWithGrail() const
|
||||
{
|
||||
for(const CGHeroInstance * h : cb->getHeroesInfo())
|
||||
for(const CGHeroInstance * h : cc->getHeroesInfo())
|
||||
{
|
||||
if(h->hasArt(ArtifactID::GRAIL))
|
||||
return h;
|
||||
|
||||
@@ -42,13 +42,13 @@ private:
|
||||
static const SecondarySkillEvaluator wariorSkillsScores;
|
||||
static const SecondarySkillEvaluator scountSkillsScores;
|
||||
|
||||
CCallback * cb; //this is enough, but we downcast from CCallback
|
||||
CCallback * cc; //this is enough, but we downcast from CCallback
|
||||
const Nullkiller * aiNk;
|
||||
std::map<HeroPtr, HeroRole> heroRoles;
|
||||
std::map<ObjectInstanceID, float> knownFightingStrength;
|
||||
|
||||
public:
|
||||
HeroManager(CCallback * CB, const Nullkiller * ai) : cb(CB), aiNk(ai) {}
|
||||
HeroManager(CCallback * cc, const Nullkiller * ai) : cc(cc), aiNk(ai) {}
|
||||
const std::map<HeroPtr, HeroRole> & getHeroRoles() const;
|
||||
HeroRole getHeroRole(const HeroPtr & hero) const;
|
||||
int selectBestSkill(const HeroPtr & hero, const std::vector<SecondarySkill> & skills) const;
|
||||
|
||||
@@ -31,14 +31,14 @@ void ObjectCluster::addObject(const CGObjectInstance * obj, const AIPath & path,
|
||||
}
|
||||
}
|
||||
|
||||
const CGObjectInstance * ObjectCluster::calculateCenter(const CPlayerSpecificInfoCallback * cb) const
|
||||
const CGObjectInstance * ObjectCluster::calculateCenter(const CPlayerSpecificInfoCallback * cpsic) const
|
||||
{
|
||||
auto tile = int3(0);
|
||||
float priority = 0;
|
||||
|
||||
for(auto & pair : objects)
|
||||
{
|
||||
auto newPoint = cb->getObj(pair.first)->visitablePos();
|
||||
auto newPoint = cpsic->getObj(pair.first)->visitablePos();
|
||||
float newPriority = std::pow(pair.second.priority, 4); // lets make high priority targets more weghtful
|
||||
int3 direction = newPoint - tile;
|
||||
float priorityRatio = newPriority / (priority + newPriority);
|
||||
@@ -49,19 +49,19 @@ const CGObjectInstance * ObjectCluster::calculateCenter(const CPlayerSpecificInf
|
||||
|
||||
auto closestPair = *vstd::minElementByFun(objects, [&](const std::pair<ObjectInstanceID, ClusterObjectInfo> & pair) -> int
|
||||
{
|
||||
return cb->getObj(pair.first)->visitablePos().dist2dSQ(tile);
|
||||
return cpsic->getObj(pair.first)->visitablePos().dist2dSQ(tile);
|
||||
});
|
||||
|
||||
return cb->getObj(closestPair.first);
|
||||
return cpsic->getObj(closestPair.first);
|
||||
}
|
||||
|
||||
std::vector<const CGObjectInstance *> ObjectCluster::getObjects(const CPlayerSpecificInfoCallback * cb) const
|
||||
std::vector<const CGObjectInstance *> ObjectCluster::getObjects(const CPlayerSpecificInfoCallback * cpsic) const
|
||||
{
|
||||
std::vector<const CGObjectInstance *> result;
|
||||
|
||||
for(auto & pair : objects)
|
||||
{
|
||||
result.push_back(cb->getObj(pair.first));
|
||||
result.push_back(cpsic->getObj(pair.first));
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
@@ -52,8 +52,8 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
std::vector<const CGObjectInstance *> getObjects(const CPlayerSpecificInfoCallback * cb) const;
|
||||
const CGObjectInstance * calculateCenter(const CPlayerSpecificInfoCallback * cb) const;
|
||||
std::vector<const CGObjectInstance *> getObjects(const CPlayerSpecificInfoCallback * cpsic) const;
|
||||
const CGObjectInstance * calculateCenter(const CPlayerSpecificInfoCallback * cpsic) const;
|
||||
};
|
||||
|
||||
using ClusterMap = tbb::concurrent_hash_map<ObjectInstanceID, std::shared_ptr<ObjectCluster>, ObjectInstanceIDHash>;
|
||||
|
||||
@@ -1216,9 +1216,9 @@ public:
|
||||
|
||||
evaluationContext.addNonCriticalStrategicalValue(potentialUpgradeValue / 10000.0f / (float)bi.prerequisitesCount);
|
||||
if(bi.id.isDwelling())
|
||||
evaluationContext.armyReward += bi.armyStrength - evaluationContext.evaluator.aiNk->armyManager->evaluateStackPower(bi.baseCreatureID.toCreature(), bi.creatureGrows);
|
||||
evaluationContext.armyReward += bi.armyStrength - evaluationContext.evaluator.aiNk->armyManager->evaluateStackPower(bi.baseCreatureID.toCreature(), bi.creatureGrowth);
|
||||
else //This is for prerequisite-buildings
|
||||
evaluationContext.armyReward += evaluationContext.evaluator.aiNk->armyManager->evaluateStackPower(bi.baseCreatureID.toCreature(), bi.creatureGrows);
|
||||
evaluationContext.armyReward += evaluationContext.evaluator.aiNk->armyManager->evaluateStackPower(bi.baseCreatureID.toCreature(), bi.creatureGrowth);
|
||||
if(alreadyOwn)
|
||||
evaluationContext.armyReward /= bi.buildCostWithPrerequisites.marketValue();
|
||||
}
|
||||
|
||||
@@ -221,7 +221,7 @@ bool BuildingManager::getBuildingOptions(const CGTownInstance * t)
|
||||
std::vector<BuildingID> extraBuildings;
|
||||
for (const auto & buildingInfo : t->getTown()->buildings)
|
||||
{
|
||||
if (buildingInfo.first.isDwelling() && BuildingID::getUpgradedFromDwelling(buildingInfo.first) > 1)
|
||||
if (buildingInfo.first.isDwelling() && BuildingID::getUpgradeNoFromDwelling(buildingInfo.first) > 1)
|
||||
extraBuildings.push_back(buildingInfo.first);
|
||||
}
|
||||
return tryBuildAnyStructure(t, extraBuildings);
|
||||
|
||||
@@ -170,7 +170,7 @@ void CBuildingRect::showPopupWindow(const Point & cursorPosition)
|
||||
}
|
||||
else
|
||||
{
|
||||
int level = BuildingID::getLevelFromDwelling(bid);
|
||||
int level = BuildingID::getLevelIndexFromDwelling(bid);
|
||||
ENGINE->windows().createAndPushWindow<CDwellingInfoBox>(parent->pos.x+parent->pos.w / 2, parent->pos.y+parent->pos.h /2, town, level);
|
||||
}
|
||||
}
|
||||
@@ -246,7 +246,7 @@ std::string CBuildingRect::getSubtitle()//hover text for building
|
||||
return town->getTown()->buildings.at(getBuilding()->bid)->getNameTranslated();
|
||||
else//dwellings - recruit %creature%
|
||||
{
|
||||
int level = BuildingID::getLevelFromDwelling(getBuilding()->bid);
|
||||
int level = BuildingID::getLevelIndexFromDwelling(getBuilding()->bid);
|
||||
auto & availableCreatures = town->creatures[level].second;
|
||||
if(availableCreatures.size())
|
||||
{
|
||||
@@ -889,7 +889,7 @@ bool CCastleBuildings::buildingTryActivateCustomUI(BuildingID buildingToTest, Bu
|
||||
|
||||
if (buildingToTest.isDwelling())
|
||||
{
|
||||
enterDwelling((BuildingID::getLevelFromDwelling(buildingToTest)));
|
||||
enterDwelling((BuildingID::getLevelIndexFromDwelling(buildingToTest)));
|
||||
return true;
|
||||
}
|
||||
else
|
||||
|
||||
@@ -289,7 +289,7 @@ public:
|
||||
class BuildingIDBase : public IdentifierBase
|
||||
{
|
||||
public:
|
||||
//Quite useful as long as most of building mechanics hardcoded
|
||||
// Quite useful as long as most of building mechanics hardcoded
|
||||
// NOTE: all building with completely configurable mechanics will be removed from list
|
||||
enum Type
|
||||
{
|
||||
@@ -369,11 +369,11 @@ public:
|
||||
throw std::runtime_error("Call to getMageGuildLevel with building '" + std::to_string(getNum()) +"' that is not mages guild!");
|
||||
}
|
||||
|
||||
static BuildingID getDwellingFromLevel(int level, int upgradeIndex)
|
||||
static BuildingID getDwellingFromLevel(int levelIndex, int upgradeIndex)
|
||||
{
|
||||
try
|
||||
{
|
||||
return getDwellings().at(upgradeIndex).at(level);
|
||||
return getDwellings().at(upgradeIndex).at(levelIndex);
|
||||
}
|
||||
catch (const std::out_of_range &)
|
||||
{
|
||||
@@ -381,7 +381,8 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
static int getLevelFromDwelling(BuildingID dwelling)
|
||||
/// @return 0 for the first one, going up to the supported no. of dwellings - 1
|
||||
static int getLevelIndexFromDwelling(BuildingID dwelling)
|
||||
{
|
||||
for (const auto & level : getDwellings())
|
||||
{
|
||||
@@ -393,7 +394,8 @@ public:
|
||||
throw std::runtime_error("Call to getLevelFromDwelling with building '" + std::to_string(dwelling.num) +"' that is not dwelling!");
|
||||
}
|
||||
|
||||
static int getUpgradedFromDwelling(BuildingID dwelling)
|
||||
/// @return 0 for no upgrade, 1 for the first one, going up to the supported no. of upgrades
|
||||
static int getUpgradeNoFromDwelling(BuildingID dwelling)
|
||||
{
|
||||
const auto & dwellings = getDwellings();
|
||||
|
||||
@@ -408,10 +410,9 @@ public:
|
||||
|
||||
static void advanceDwelling(BuildingID & dwelling)
|
||||
{
|
||||
int level = getLevelFromDwelling(dwelling);
|
||||
int upgrade = getUpgradedFromDwelling(dwelling);
|
||||
|
||||
dwelling = getDwellingFromLevel(level, upgrade + 1);
|
||||
int levelIndex = getLevelIndexFromDwelling(dwelling);
|
||||
int upgradeNo = getUpgradeNoFromDwelling(dwelling);
|
||||
dwelling = getDwellingFromLevel(levelIndex, upgradeNo + 1);
|
||||
}
|
||||
|
||||
bool isDwelling() const
|
||||
|
||||
@@ -2088,8 +2088,8 @@ bool CGameHandler::buildStructure(ObjectInstanceID tid, BuildingID requestedID,
|
||||
{
|
||||
if(buildingID.isDwelling())
|
||||
{
|
||||
int level = BuildingID::getLevelFromDwelling(buildingID);
|
||||
int upgradeNumber = BuildingID::getUpgradedFromDwelling(buildingID);
|
||||
int level = BuildingID::getLevelIndexFromDwelling(buildingID);
|
||||
int upgradeNumber = BuildingID::getUpgradeNoFromDwelling(buildingID);
|
||||
|
||||
if(upgradeNumber >= t->getTown()->creatures.at(level).size())
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user