1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-11-28 08:48:48 +02:00

NKAI: fix casting FLY several times during path calculation

This commit is contained in:
Andrii Danylchenko 2023-12-23 15:53:30 +02:00
parent 36bc9ddcec
commit 1db43a509e
6 changed files with 51 additions and 11 deletions

View File

@ -137,6 +137,18 @@ TResources getCreatureBankResources(const CGObjectInstance * target, const CGHer
return sum > 1 ? result / sum : result;
}
uint64_t getResourcesGoldReward(TResources & res)
{
int nonGoldResources = res[EGameResID::GEMS]
+ res[EGameResID::SULFUR]
+ res[EGameResID::WOOD]
+ res[EGameResID::ORE]
+ res[EGameResID::CRYSTAL]
+ res[EGameResID::MERCURY];
return res[EGameResID::GOLD] + 100 * nonGoldResources;
}
uint64_t getCreatureBankArmyReward(const CGObjectInstance * target, const CGHeroInstance * hero)
{
auto objectInfo = target->getObjectHandler()->getObjectInfo(target->appearance);
@ -491,7 +503,7 @@ float RewardEvaluator::getStrategicalValue(const CGObjectInstance * target) cons
//Evaluate resources used for construction. Gold is evaluated separately.
if (it->resType != EGameResID::GOLD)
{
sum += 0.1f * getResourceRequirementStrength(it->resType);
sum += 0.1f * it->resVal * getResourceRequirementStrength(it->resType);
}
}
return sum;
@ -662,7 +674,7 @@ int32_t RewardEvaluator::getGoldReward(const CGObjectInstance * target, const CG
case Obj::WAGON:
return 100;
case Obj::CREATURE_BANK:
return getCreatureBankResources(target, hero)[EGameResID::GOLD];
return getResourcesGoldReward(getCreatureBankResources(target, hero));
case Obj::CRYPT:
case Obj::DERELICT_SHIP:
return 3000;

View File

@ -234,6 +234,7 @@ void AINodeStorage::resetTile(const int3 & coord, EPathfindingLayer layer, EPath
heroNode.specialAction.reset();
heroNode.armyLoss = 0;
heroNode.chainOther = nullptr;
heroNode.dayFlags = DayFlags::NONE;
heroNode.update(coord, layer, accessibility);
}
}
@ -295,6 +296,11 @@ void AINodeStorage::commit(
{
commitedTiles.insert(destination->coord);
}
if(destination->turns == source->turns)
{
destination->dayFlags = source->dayFlags;
}
}
std::vector<CGPathNode *> AINodeStorage::calculateNeighbours(

View File

@ -41,11 +41,19 @@ namespace AIPathfinding
const int CHAIN_MAX_DEPTH = 4;
}
enum DayFlags : ui8
{
NONE = 0,
FLY_CASTED = 1,
WATER_WALK_CASTED = 2
};
struct AIPathNode : public CGPathNode
{
uint64_t danger;
uint64_t armyLoss;
int32_t manaCost;
int16_t manaCost;
DayFlags dayFlags;
const AIPathNode * chainOther;
std::shared_ptr<const SpecialAction> specialAction;
const ChainActor * actor;

View File

@ -22,18 +22,18 @@ namespace NKAI
namespace AIPathfinding
{
AdventureCastAction::AdventureCastAction(SpellID spellToCast, const CGHeroInstance * hero)
:spellToCast(spellToCast), hero(hero)
AdventureCastAction::AdventureCastAction(SpellID spellToCast, const CGHeroInstance * hero, DayFlags flagsToAdd)
:spellToCast(spellToCast), hero(hero), flagsToAdd(flagsToAdd)
{
manaCost = hero->getSpellCost(spellToCast.toSpell());
}
WaterWalkingAction::WaterWalkingAction(const CGHeroInstance * hero)
:AdventureCastAction(SpellID::WATER_WALK, hero)
:AdventureCastAction(SpellID::WATER_WALK, hero, DayFlags::WATER_WALK_CASTED)
{ }
AirWalkingAction::AirWalkingAction(const CGHeroInstance * hero)
: AdventureCastAction(SpellID::FLY, hero)
: AdventureCastAction(SpellID::FLY, hero, DayFlags::FLY_CASTED)
{
}
@ -41,11 +41,12 @@ namespace AIPathfinding
const CGHeroInstance * hero,
CDestinationNodeInfo & destination,
const PathNodeInfo & source,
AIPathNode * dstMode,
AIPathNode * dstNode,
const AIPathNode * srcNode) const
{
dstMode->manaCost = srcNode->manaCost + manaCost;
dstMode->theNodeBefore = source.node;
dstNode->manaCost = srcNode->manaCost + manaCost;
dstNode->theNodeBefore = source.node;
dstNode->dayFlags = static_cast<DayFlags>(dstNode->dayFlags | flagsToAdd);
}
void AdventureCastAction::execute(const CGHeroInstance * hero) const

View File

@ -24,9 +24,10 @@ namespace AIPathfinding
SpellID spellToCast;
const CGHeroInstance * hero;
int manaCost;
DayFlags flagsToAdd;
public:
AdventureCastAction(SpellID spellToCast, const CGHeroInstance * hero);
AdventureCastAction(SpellID spellToCast, const CGHeroInstance * hero, DayFlags flagsToAdd = DayFlags::NONE);
virtual void execute(const CGHeroInstance * hero) const override;

View File

@ -61,6 +61,12 @@ namespace AIPathfinding
if(source.node->layer == EPathfindingLayer::LAND && destination.node->layer == EPathfindingLayer::WATER)
{
if(nodeStorage->getAINode(source.node)->dayFlags & DayFlags::WATER_WALK_CASTED)
{
destination.blocked = false;
return;
}
auto action = waterWalkingActions.find(nodeStorage->getHero(source.node));
if(action != waterWalkingActions.end() && tryUseSpecialAction(destination, source, action->second, EPathNodeAction::NORMAL))
@ -73,6 +79,12 @@ namespace AIPathfinding
if(source.node->layer == EPathfindingLayer::LAND && destination.node->layer == EPathfindingLayer::AIR)
{
if(nodeStorage->getAINode(source.node)->dayFlags & DayFlags::FLY_CASTED)
{
destination.blocked = false;
return;
}
auto action = airWalkingActions.find(nodeStorage->getHero(source.node));
if(action != airWalkingActions.end() && tryUseSpecialAction(destination, source, action->second, EPathNodeAction::NORMAL))