mirror of
https://github.com/vcmi/vcmi.git
synced 2025-04-17 11:56:46 +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)
|
void AINodeStorage::initialize(const PathfinderOptions & options, const CGameState * gs)
|
||||||
{
|
{
|
||||||
if(heroChainPass)
|
if(heroChainPass != EHeroChainPass::INITIAL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
AISharedStorage::version++;
|
AISharedStorage::version++;
|
||||||
@ -157,6 +157,7 @@ void AINodeStorage::initialize(const PathfinderOptions & options, const CGameSta
|
|||||||
void AINodeStorage::clear()
|
void AINodeStorage::clear()
|
||||||
{
|
{
|
||||||
actors.clear();
|
actors.clear();
|
||||||
|
commitedTiles.clear();
|
||||||
heroChainPass = EHeroChainPass::INITIAL;
|
heroChainPass = EHeroChainPass::INITIAL;
|
||||||
heroChainTurn = 0;
|
heroChainTurn = 0;
|
||||||
heroChainMaxTurns = 1;
|
heroChainMaxTurns = 1;
|
||||||
@ -169,7 +170,7 @@ std::optional<AIPathNode *> AINodeStorage::getOrCreateNode(
|
|||||||
const EPathfindingLayer layer,
|
const EPathfindingLayer layer,
|
||||||
const ChainActor * actor)
|
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;
|
int bucketOffset = bucketIndex * AIPathfinding::BUCKET_SIZE;
|
||||||
auto chains = nodes.get(pos);
|
auto chains = nodes.get(pos);
|
||||||
|
|
||||||
@ -330,10 +331,38 @@ void AINodeStorage::calculateNeighbours(
|
|||||||
|
|
||||||
for(auto & neighbour : accessibleNeighbourTiles)
|
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);
|
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;
|
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());
|
result.push_back(nextNode.value());
|
||||||
}
|
}
|
||||||
|
@ -47,6 +47,7 @@ namespace AIPathfinding
|
|||||||
:PathfinderConfig(nodeStorage, makeRuleset(cb, ai, nodeStorage, allowBypassObjects)), aiNodeStorage(nodeStorage)
|
:PathfinderConfig(nodeStorage, makeRuleset(cb, ai, nodeStorage, allowBypassObjects)), aiNodeStorage(nodeStorage)
|
||||||
{
|
{
|
||||||
options.canUseCast = true;
|
options.canUseCast = true;
|
||||||
|
options.allowLayerTransitioningAfterBattle = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
AIPathfinderConfig::~AIPathfinderConfig() = default;
|
AIPathfinderConfig::~AIPathfinderConfig() = default;
|
||||||
|
@ -34,6 +34,14 @@ namespace AIPathfinding
|
|||||||
{
|
{
|
||||||
LayerTransitionRule::process(source, destination, pathfinderConfig, pathfinderHelper);
|
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(!destination.blocked)
|
||||||
{
|
{
|
||||||
if(source.node->layer == EPathfindingLayer::LAND
|
if(source.node->layer == EPathfindingLayer::LAND
|
||||||
|
@ -84,10 +84,11 @@ namespace AIPathfinding
|
|||||||
|
|
||||||
#if NKAI_PATHFINDER_TRACE_LEVEL >= 2
|
#if NKAI_PATHFINDER_TRACE_LEVEL >= 2
|
||||||
logAi->trace(
|
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(),
|
destination.coord.toString(),
|
||||||
(int)destination.action,
|
(int)destination.action,
|
||||||
(int)blocker);
|
(int)blocker,
|
||||||
|
source.coord.toString());
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
auto destGuardians = cb->getGuardingCreatures(destination.coord);
|
auto destGuardians = cb->getGuardingCreatures(destination.coord);
|
||||||
|
@ -330,7 +330,7 @@ bool CPathfinder::isLayerTransitionPossible() const
|
|||||||
ELayer destLayer = destination.node->layer;
|
ELayer destLayer = destination.node->layer;
|
||||||
|
|
||||||
/// No layer transition allowed when previous node action is BATTLE
|
/// 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;
|
return false;
|
||||||
|
|
||||||
switch(source.node->layer.toEnum())
|
switch(source.node->layer.toEnum())
|
||||||
|
@ -33,6 +33,7 @@ PathfinderOptions::PathfinderOptions()
|
|||||||
, oneTurnSpecialLayersLimit(true)
|
, oneTurnSpecialLayersLimit(true)
|
||||||
, turnLimit(std::numeric_limits<uint8_t>::max())
|
, turnLimit(std::numeric_limits<uint8_t>::max())
|
||||||
, canUseCast(false)
|
, canUseCast(false)
|
||||||
|
, allowLayerTransitioningAfterBattle(false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,6 +79,11 @@ struct DLL_LINKAGE PathfinderOptions
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
bool canUseCast;
|
bool canUseCast;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// For AI. AI pathfinder needs to ignore this rule as it simulates battles on the way
|
||||||
|
/// </summary>
|
||||||
|
bool allowLayerTransitioningAfterBattle;
|
||||||
|
|
||||||
PathfinderOptions();
|
PathfinderOptions();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user