1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-12-02 09:02:03 +02:00

Merge pull request #3892 from vcmi/fix-3876

#3876 - allow to embark after battle for AI pathfinder
This commit is contained in:
Andrii Danylchenko 2024-05-06 10:52:41 +03:00 committed by GitHub
commit 5ea720cd8e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 51 additions and 6 deletions

View File

@ -104,7 +104,7 @@ AINodeStorage::~AINodeStorage() = default;
void AINodeStorage::initialize(const PathfinderOptions & options, const CGameState * gs)
{
if(heroChainPass)
if(heroChainPass != EHeroChainPass::INITIAL)
return;
AISharedStorage::version++;
@ -157,6 +157,7 @@ void AINodeStorage::initialize(const PathfinderOptions & options, const CGameSta
void AINodeStorage::clear()
{
actors.clear();
commitedTiles.clear();
heroChainPass = EHeroChainPass::INITIAL;
heroChainTurn = 0;
heroChainMaxTurns = 1;
@ -169,7 +170,7 @@ std::optional<AIPathNode *> AINodeStorage::getOrCreateNode(
const EPathfindingLayer layer,
const ChainActor * actor)
{
int bucketIndex = ((uintptr_t)actor) % AIPathfinding::BUCKET_COUNT;
int bucketIndex = ((uintptr_t)actor + static_cast<uint32_t>(layer)) % AIPathfinding::BUCKET_COUNT;
int bucketOffset = bucketIndex * AIPathfinding::BUCKET_SIZE;
auto chains = nodes.get(pos);
@ -330,10 +331,38 @@ void AINodeStorage::calculateNeighbours(
for(auto & neighbour : accessibleNeighbourTiles)
{
if(getAccessibility(neighbour, layer) == EPathAccessibility::NOT_SET)
{
#if NKAI_PATHFINDER_TRACE_LEVEL >= 2
logAi->trace(
"Node %s rejected for %s, layer %d because of inaccessibility",
neighbour.toString(),
source.coord.toString(),
static_cast<int32_t>(layer));
#endif
continue;
}
auto nextNode = getOrCreateNode(neighbour, layer, srcNode->actor);
if(!nextNode || nextNode.value()->accessible == EPathAccessibility::NOT_SET)
if(!nextNode)
{
#if NKAI_PATHFINDER_TRACE_LEVEL >= 2
logAi->trace(
"Failed to allocate node at %s[%d]",
neighbour.toString(),
static_cast<int32_t>(layer));
#endif
continue;
}
#if NKAI_PATHFINDER_TRACE_LEVEL >= 2
logAi->trace(
"Node %s added to neighbors of %s, layer %d",
neighbour.toString(),
source.coord.toString(),
static_cast<int32_t>(layer));
#endif
result.push_back(nextNode.value());
}

View File

@ -47,6 +47,7 @@ namespace AIPathfinding
:PathfinderConfig(nodeStorage, makeRuleset(cb, ai, nodeStorage, allowBypassObjects)), aiNodeStorage(nodeStorage)
{
options.canUseCast = true;
options.allowLayerTransitioningAfterBattle = true;
}
AIPathfinderConfig::~AIPathfinderConfig() = default;

View File

@ -34,6 +34,14 @@ namespace AIPathfinding
{
LayerTransitionRule::process(source, destination, pathfinderConfig, pathfinderHelper);
#if NKAI_PATHFINDER_TRACE_LEVEL >= 2
logAi->trace("Layer transitioning %s -> %s, action: %d, blocked: %s",
source.coord.toString(),
destination.coord.toString(),
static_cast<int32_t>(destination.action),
destination.blocked ? "true" : "false");
#endif
if(!destination.blocked)
{
if(source.node->layer == EPathfindingLayer::LAND

View File

@ -84,10 +84,11 @@ namespace AIPathfinding
#if NKAI_PATHFINDER_TRACE_LEVEL >= 2
logAi->trace(
"Movement from tile %s is blocked. Try to bypass. Action: %d, blocker: %d",
"Movement from tile %s is blocked. Try to bypass. Action: %d, blocker: %d, source: %s",
destination.coord.toString(),
(int)destination.action,
(int)blocker);
(int)blocker,
source.coord.toString());
#endif
auto destGuardians = cb->getGuardingCreatures(destination.coord);

View File

@ -330,7 +330,7 @@ bool CPathfinder::isLayerTransitionPossible() const
ELayer destLayer = destination.node->layer;
/// No layer transition allowed when previous node action is BATTLE
if(source.node->action == EPathNodeAction::BATTLE)
if(!config->options.allowLayerTransitioningAfterBattle && source.node->action == EPathNodeAction::BATTLE)
return false;
switch(source.node->layer.toEnum())

View File

@ -33,6 +33,7 @@ PathfinderOptions::PathfinderOptions()
, oneTurnSpecialLayersLimit(true)
, turnLimit(std::numeric_limits<uint8_t>::max())
, canUseCast(false)
, allowLayerTransitioningAfterBattle(false)
{
}

View File

@ -79,6 +79,11 @@ struct DLL_LINKAGE PathfinderOptions
/// </summary>
bool canUseCast;
/// <summary>
/// For AI. AI pathfinder needs to ignore this rule as it simulates battles on the way
/// </summary>
bool allowLayerTransitioningAfterBattle;
PathfinderOptions();
};