1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-08-08 22:26:51 +02:00

AI will now devalue the usefulness of non-flying units when attacking defensive structures in order to prevent suiciding against castles

This commit is contained in:
Xilmi
2024-12-28 12:40:44 +01:00
committed by Ivan Savenko
parent d3987d8456
commit 6c4996ff54
6 changed files with 33 additions and 10 deletions

View File

@@ -774,9 +774,9 @@ bool townHasFreeTavern(const CGTownInstance * town)
return canMoveVisitingHeroToGarrison;
}
uint64_t getHeroArmyStrengthWithCommander(const CGHeroInstance * hero, const CCreatureSet * heroArmy)
uint64_t getHeroArmyStrengthWithCommander(const CGHeroInstance * hero, const CCreatureSet * heroArmy, int fortLevel)
{
auto armyStrength = heroArmy->getArmyStrength();
auto armyStrength = heroArmy->getArmyStrength(fortLevel);
if(hero && hero->commander && hero->commander->alive)
{

View File

@@ -217,7 +217,7 @@ int64_t getArtifactScoreForHero(const CGHeroInstance * hero, const CArtifactInst
int64_t getPotentialArtifactScore(const CArtifact * art);
bool townHasFreeTavern(const CGTownInstance * town);
uint64_t getHeroArmyStrengthWithCommander(const CGHeroInstance * hero, const CCreatureSet * heroArmy);
uint64_t getHeroArmyStrengthWithCommander(const CGHeroInstance * hero, const CCreatureSet * heroArmy, int fortLevel = 0);
uint64_t timeElapsed(std::chrono::time_point<std::chrono::high_resolution_clock> start);

View File

@@ -127,9 +127,9 @@ ui64 FuzzyHelper::evaluateDanger(const CGObjectInstance * obj)
auto fortLevel = town->fortLevel();
if (fortLevel == CGTownInstance::EFortLevel::CASTLE)
danger = std::max(danger * 2, danger + 10000);
danger += 10000;
else if(fortLevel == CGTownInstance::EFortLevel::CITADEL)
danger = std::max(ui64(danger * 1.4), danger + 4000);
danger += 4000;
}
return danger;

View File

@@ -1447,9 +1447,20 @@ void AINodeStorage::calculateChainInfo(std::vector<AIPath> & paths, const int3 &
}
}
int fortLevel = 0;
auto visitableObjects = cb->getVisitableObjs(pos);
for (auto obj : visitableObjects)
{
if (objWithID<Obj::TOWN>(obj))
{
auto town = dynamic_cast<const CGTownInstance*>(obj);
fortLevel = town->fortLevel();
}
}
path.targetObjectArmyLoss = evaluateArmyLoss(
path.targetHero,
getHeroArmyStrengthWithCommander(path.targetHero, path.heroArmy),
getHeroArmyStrengthWithCommander(path.targetHero, path.heroArmy, fortLevel),
path.targetObjectDanger);
path.chainMask = node.actor->chainMask;

View File

@@ -353,11 +353,23 @@ bool CCreatureSet::needsLastStack() const
return false;
}
ui64 CCreatureSet::getArmyStrength() const
ui64 CCreatureSet::getArmyStrength(int fortLevel) const
{
ui64 ret = 0;
for(const auto & elem : stacks)
ret += elem.second->getPower();
for (const auto& elem : stacks)
{
ui64 powerToAdd = elem.second->getPower();
if (fortLevel > 0)
{
if (!elem.second->hasBonusOfType(BonusType::FLYING))
{
powerToAdd /= fortLevel;
if (!elem.second->hasBonusOfType(BonusType::SHOOTER))
powerToAdd /= fortLevel;
}
}
ret += powerToAdd;
}
return ret;
}

View File

@@ -283,7 +283,7 @@ public:
bool slotEmpty(const SlotID & slot) const;
int stacksCount() const;
virtual bool needsLastStack() const; //true if last stack cannot be taken
ui64 getArmyStrength() const; //sum of AI values of creatures
ui64 getArmyStrength(int fortLevel = 0) const; //sum of AI values of creatures
ui64 getArmyCost() const; //sum of cost of creatures
ui64 getPower(const SlotID & slot) const; //value of specific stack
std::string getRoughAmount(const SlotID & slot, int mode = 0) const; //rough size of specific stack