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:
commit
5ea720cd8e
@ -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());
|
||||
}
|
||||
|
@ -47,6 +47,7 @@ namespace AIPathfinding
|
||||
:PathfinderConfig(nodeStorage, makeRuleset(cb, ai, nodeStorage, allowBypassObjects)), aiNodeStorage(nodeStorage)
|
||||
{
|
||||
options.canUseCast = true;
|
||||
options.allowLayerTransitioningAfterBattle = true;
|
||||
}
|
||||
|
||||
AIPathfinderConfig::~AIPathfinderConfig() = default;
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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())
|
||||
|
@ -33,6 +33,7 @@ PathfinderOptions::PathfinderOptions()
|
||||
, oneTurnSpecialLayersLimit(true)
|
||||
, turnLimit(std::numeric_limits<uint8_t>::max())
|
||||
, canUseCast(false)
|
||||
, allowLayerTransitioningAfterBattle(false)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user