mirror of
https://github.com/vcmi/vcmi.git
synced 2025-10-08 23:22:25 +02:00
Converted pathfinder enum's to enum class
This commit is contained in:
@@ -1196,11 +1196,11 @@ bool AIGateway::moveHeroToTile(int3 dst, HeroPtr h)
|
|||||||
//return cb->getTile(coord,false)->topVisitableObj(ignoreHero);
|
//return cb->getTile(coord,false)->topVisitableObj(ignoreHero);
|
||||||
};
|
};
|
||||||
|
|
||||||
auto isTeleportAction = [&](CGPathNode::ENodeAction action) -> bool
|
auto isTeleportAction = [&](EPathNodeAction action) -> bool
|
||||||
{
|
{
|
||||||
if(action != CGPathNode::TELEPORT_NORMAL && action != CGPathNode::TELEPORT_BLOCKING_VISIT)
|
if(action != EPathNodeAction::TELEPORT_NORMAL && action != EPathNodeAction::TELEPORT_BLOCKING_VISIT)
|
||||||
{
|
{
|
||||||
if(action != CGPathNode::TELEPORT_BATTLE)
|
if(action != EPathNodeAction::TELEPORT_BATTLE)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -1311,7 +1311,7 @@ bool AIGateway::moveHeroToTile(int3 dst, HeroPtr h)
|
|||||||
doChannelProbing();
|
doChannelProbing();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(path.nodes[0].action == CGPathNode::BLOCKING_VISIT || path.nodes[0].action == CGPathNode::BATTLE)
|
if(path.nodes[0].action == EPathNodeAction::BLOCKING_VISIT || path.nodes[0].action == EPathNodeAction::BATTLE)
|
||||||
{
|
{
|
||||||
// when we take resource we do not reach its position. We even might not move
|
// when we take resource we do not reach its position. We even might not move
|
||||||
// also guarded town is not get visited automatically after capturing
|
// also guarded town is not get visited automatically after capturing
|
||||||
|
@@ -103,9 +103,9 @@ void ExecuteHeroChain::accept(AIGateway * ai)
|
|||||||
{
|
{
|
||||||
auto targetNode = cb->getPathsInfo(hero)->getPathInfo(node.coord);
|
auto targetNode = cb->getPathsInfo(hero)->getPathInfo(node.coord);
|
||||||
|
|
||||||
if(targetNode->accessible == CGPathNode::EAccessibility::NOT_SET
|
if(targetNode->accessible == EPathAccessibility::NOT_SET
|
||||||
|| targetNode->accessible == CGPathNode::EAccessibility::BLOCKED
|
|| targetNode->accessible == EPathAccessibility::BLOCKED
|
||||||
|| targetNode->accessible == CGPathNode::EAccessibility::FLYABLE
|
|| targetNode->accessible == EPathAccessibility::FLYABLE
|
||||||
|| targetNode->turns != 0)
|
|| targetNode->turns != 0)
|
||||||
{
|
{
|
||||||
logAi->error(
|
logAi->error(
|
||||||
|
@@ -206,7 +206,7 @@ std::vector<CGPathNode *> AINodeStorage::getInitialNodes()
|
|||||||
initialNode->moveRemains = actor->initialMovement;
|
initialNode->moveRemains = actor->initialMovement;
|
||||||
initialNode->danger = 0;
|
initialNode->danger = 0;
|
||||||
initialNode->setCost(actor->initialTurn);
|
initialNode->setCost(actor->initialTurn);
|
||||||
initialNode->action = CGPathNode::ENodeAction::NORMAL;
|
initialNode->action = EPathNodeAction::NORMAL;
|
||||||
|
|
||||||
if(actor->isMovable)
|
if(actor->isMovable)
|
||||||
{
|
{
|
||||||
@@ -224,7 +224,7 @@ std::vector<CGPathNode *> AINodeStorage::getInitialNodes()
|
|||||||
return initialNodes;
|
return initialNodes;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AINodeStorage::resetTile(const int3 & coord, EPathfindingLayer layer, CGPathNode::EAccessibility accessibility)
|
void AINodeStorage::resetTile(const int3 & coord, EPathfindingLayer layer, EPathAccessibility accessibility)
|
||||||
{
|
{
|
||||||
for(AIPathNode & heroNode : nodes.get(coord, layer))
|
for(AIPathNode & heroNode : nodes.get(coord, layer))
|
||||||
{
|
{
|
||||||
@@ -262,7 +262,7 @@ void AINodeStorage::commit(CDestinationNodeInfo & destination, const PathNodeInf
|
|||||||
void AINodeStorage::commit(
|
void AINodeStorage::commit(
|
||||||
AIPathNode * destination,
|
AIPathNode * destination,
|
||||||
const AIPathNode * source,
|
const AIPathNode * source,
|
||||||
CGPathNode::ENodeAction action,
|
EPathNodeAction action,
|
||||||
int turn,
|
int turn,
|
||||||
int movementLeft,
|
int movementLeft,
|
||||||
float cost) const
|
float cost) const
|
||||||
@@ -312,7 +312,7 @@ std::vector<CGPathNode *> AINodeStorage::calculateNeighbours(
|
|||||||
{
|
{
|
||||||
auto nextNode = getOrCreateNode(neighbour, i, srcNode->actor);
|
auto nextNode = getOrCreateNode(neighbour, i, srcNode->actor);
|
||||||
|
|
||||||
if(!nextNode || nextNode.value()->accessible == CGPathNode::NOT_SET)
|
if(!nextNode || nextNode.value()->accessible == EPathAccessibility::NOT_SET)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
neighbours.push_back(nextNode.value());
|
neighbours.push_back(nextNode.value());
|
||||||
@@ -342,7 +342,7 @@ bool AINodeStorage::increaseHeroChainTurnLimit()
|
|||||||
{
|
{
|
||||||
for(AIPathNode & node : chains)
|
for(AIPathNode & node : chains)
|
||||||
{
|
{
|
||||||
if(node.turns <= heroChainTurn && node.action != CGPathNode::ENodeAction::UNKNOWN)
|
if(node.turns <= heroChainTurn && node.action != EPathNodeAction::UNKNOWN)
|
||||||
{
|
{
|
||||||
commitedTiles.insert(pos);
|
commitedTiles.insert(pos);
|
||||||
break;
|
break;
|
||||||
@@ -372,7 +372,7 @@ bool AINodeStorage::calculateHeroChainFinal()
|
|||||||
{
|
{
|
||||||
if(node.turns > heroChainTurn
|
if(node.turns > heroChainTurn
|
||||||
&& !node.locked
|
&& !node.locked
|
||||||
&& node.action != CGPathNode::ENodeAction::UNKNOWN
|
&& node.action != EPathNodeAction::UNKNOWN
|
||||||
&& node.actor->actorExchangeCount > 1
|
&& node.actor->actorExchangeCount > 1
|
||||||
&& !hasBetterChain(&node, &node, chains))
|
&& !hasBetterChain(&node, &node, chains))
|
||||||
{
|
{
|
||||||
@@ -444,7 +444,7 @@ public:
|
|||||||
|
|
||||||
for(AIPathNode & node : chains)
|
for(AIPathNode & node : chains)
|
||||||
{
|
{
|
||||||
if(node.turns <= heroChainTurn && node.action != CGPathNode::ENodeAction::UNKNOWN)
|
if(node.turns <= heroChainTurn && node.action != EPathNodeAction::UNKNOWN)
|
||||||
existingChains.push_back(&node);
|
existingChains.push_back(&node);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -644,16 +644,16 @@ void HeroChainCalculationTask::calculateHeroChain(
|
|||||||
if(node->actor->actorExchangeCount + srcNode->actor->actorExchangeCount > CHAIN_MAX_DEPTH)
|
if(node->actor->actorExchangeCount + srcNode->actor->actorExchangeCount > CHAIN_MAX_DEPTH)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if(node->action == CGPathNode::ENodeAction::BATTLE
|
if(node->action == EPathNodeAction::BATTLE
|
||||||
|| node->action == CGPathNode::ENodeAction::TELEPORT_BATTLE
|
|| node->action == EPathNodeAction::TELEPORT_BATTLE
|
||||||
|| node->action == CGPathNode::ENodeAction::TELEPORT_NORMAL
|
|| node->action == EPathNodeAction::TELEPORT_NORMAL
|
||||||
|| node->action == CGPathNode::ENodeAction::TELEPORT_BLOCKING_VISIT)
|
|| node->action == EPathNodeAction::TELEPORT_BLOCKING_VISIT)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(node->turns > heroChainTurn
|
if(node->turns > heroChainTurn
|
||||||
|| (node->action == CGPathNode::ENodeAction::UNKNOWN && node->actor->hero)
|
|| (node->action == EPathNodeAction::UNKNOWN && node->actor->hero)
|
||||||
|| (node->actor->chainMask & srcNode->actor->chainMask) != 0)
|
|| (node->actor->chainMask & srcNode->actor->chainMask) != 0)
|
||||||
{
|
{
|
||||||
#if NKAI_PATHFINDER_TRACE_LEVEL >= 2
|
#if NKAI_PATHFINDER_TRACE_LEVEL >= 2
|
||||||
@@ -666,7 +666,7 @@ void HeroChainCalculationTask::calculateHeroChain(
|
|||||||
srcNode->coord.toString(),
|
srcNode->coord.toString(),
|
||||||
(node->turns > heroChainTurn
|
(node->turns > heroChainTurn
|
||||||
? "turn limit"
|
? "turn limit"
|
||||||
: (node->action == CGPathNode::ENodeAction::UNKNOWN && node->actor->hero)
|
: (node->action == EPathNodeAction::UNKNOWN && node->actor->hero)
|
||||||
? "action unknown"
|
? "action unknown"
|
||||||
: "chain mask"));
|
: "chain mask"));
|
||||||
#endif
|
#endif
|
||||||
@@ -693,8 +693,8 @@ void HeroChainCalculationTask::calculateHeroChain(
|
|||||||
std::vector<ExchangeCandidate> & result)
|
std::vector<ExchangeCandidate> & result)
|
||||||
{
|
{
|
||||||
if(carrier->armyLoss < carrier->actor->armyValue
|
if(carrier->armyLoss < carrier->actor->armyValue
|
||||||
&& (carrier->action != CGPathNode::BATTLE || (carrier->actor->allowBattle && carrier->specialAction))
|
&& (carrier->action != EPathNodeAction::BATTLE || (carrier->actor->allowBattle && carrier->specialAction))
|
||||||
&& carrier->action != CGPathNode::BLOCKING_VISIT
|
&& carrier->action != EPathNodeAction::BLOCKING_VISIT
|
||||||
&& (other->armyLoss == 0 || other->armyLoss < other->actor->armyValue))
|
&& (other->armyLoss == 0 || other->armyLoss < other->actor->armyValue))
|
||||||
{
|
{
|
||||||
#if NKAI_PATHFINDER_TRACE_LEVEL >= 2
|
#if NKAI_PATHFINDER_TRACE_LEVEL >= 2
|
||||||
@@ -747,7 +747,7 @@ void HeroChainCalculationTask::addHeroChain(const std::vector<ExchangeCandidate>
|
|||||||
|
|
||||||
auto exchangeNode = chainNodeOptional.value();
|
auto exchangeNode = chainNodeOptional.value();
|
||||||
|
|
||||||
if(exchangeNode->action != CGPathNode::ENodeAction::UNKNOWN)
|
if(exchangeNode->action != EPathNodeAction::UNKNOWN)
|
||||||
{
|
{
|
||||||
#if NKAI_PATHFINDER_TRACE_LEVEL >= 2
|
#if NKAI_PATHFINDER_TRACE_LEVEL >= 2
|
||||||
logAi->trace(
|
logAi->trace(
|
||||||
@@ -1057,12 +1057,12 @@ struct TowmPortalFinder
|
|||||||
|
|
||||||
movementCost += bestNode->getCost();
|
movementCost += bestNode->getCost();
|
||||||
|
|
||||||
if(node->action == CGPathNode::UNKNOWN || node->getCost() > movementCost)
|
if(node->action == EPathNodeAction::UNKNOWN || node->getCost() > movementCost)
|
||||||
{
|
{
|
||||||
nodeStorage->commit(
|
nodeStorage->commit(
|
||||||
node,
|
node,
|
||||||
nodeStorage->getAINode(bestNode),
|
nodeStorage->getAINode(bestNode),
|
||||||
CGPathNode::TELEPORT_NORMAL,
|
EPathNodeAction::TELEPORT_NORMAL,
|
||||||
bestNode->turns,
|
bestNode->turns,
|
||||||
bestNode->moveRemains - movementNeeded,
|
bestNode->moveRemains - movementNeeded,
|
||||||
movementCost);
|
movementCost);
|
||||||
@@ -1190,7 +1190,7 @@ bool AINodeStorage::hasBetterChain(
|
|||||||
{
|
{
|
||||||
auto sameNode = node.actor == candidateNode->actor;
|
auto sameNode = node.actor == candidateNode->actor;
|
||||||
|
|
||||||
if(sameNode || node.action == CGPathNode::ENodeAction::UNKNOWN || !node.actor || !node.actor->hero)
|
if(sameNode || node.action == EPathNodeAction::UNKNOWN || !node.actor || !node.actor->hero)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -1273,7 +1273,7 @@ bool AINodeStorage::isTileAccessible(const HeroPtr & hero, const int3 & pos, con
|
|||||||
|
|
||||||
for(const AIPathNode & node : chains)
|
for(const AIPathNode & node : chains)
|
||||||
{
|
{
|
||||||
if(node.action != CGPathNode::ENodeAction::UNKNOWN
|
if(node.action != EPathNodeAction::UNKNOWN
|
||||||
&& node.actor && node.actor->hero == hero.h)
|
&& node.actor && node.actor->hero == hero.h)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
@@ -1293,7 +1293,7 @@ std::vector<AIPath> AINodeStorage::getChainInfo(const int3 & pos, bool isOnLand)
|
|||||||
|
|
||||||
for(const AIPathNode & node : chains)
|
for(const AIPathNode & node : chains)
|
||||||
{
|
{
|
||||||
if(node.action == CGPathNode::ENodeAction::UNKNOWN || !node.actor || !node.actor->hero)
|
if(node.action == EPathNodeAction::UNKNOWN || !node.actor || !node.actor->hero)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@@ -53,8 +53,8 @@ struct AIPathNode : public CGPathNode
|
|||||||
STRONG_INLINE
|
STRONG_INLINE
|
||||||
bool blocked() const
|
bool blocked() const
|
||||||
{
|
{
|
||||||
return accessible == CGPathNode::EAccessibility::NOT_SET
|
return accessible == EPathAccessibility::NOT_SET
|
||||||
|| accessible == CGPathNode::EAccessibility::BLOCKED;
|
|| accessible == EPathAccessibility::BLOCKED;
|
||||||
}
|
}
|
||||||
|
|
||||||
void addSpecialAction(std::shared_ptr<const SpecialAction> action);
|
void addSpecialAction(std::shared_ptr<const SpecialAction> action);
|
||||||
@@ -196,7 +196,7 @@ public:
|
|||||||
void commit(
|
void commit(
|
||||||
AIPathNode * destination,
|
AIPathNode * destination,
|
||||||
const AIPathNode * source,
|
const AIPathNode * source,
|
||||||
CGPathNode::ENodeAction action,
|
EPathNodeAction action,
|
||||||
int turn,
|
int turn,
|
||||||
int movementLeft,
|
int movementLeft,
|
||||||
float cost) const;
|
float cost) const;
|
||||||
@@ -262,7 +262,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
STRONG_INLINE
|
STRONG_INLINE
|
||||||
void resetTile(const int3 & tile, EPathfindingLayer layer, CGPathNode::EAccessibility accessibility);
|
void resetTile(const int3 & tile, EPathfindingLayer layer, EPathAccessibility accessibility);
|
||||||
|
|
||||||
STRONG_INLINE int getBucket(const ChainActor * actor) const
|
STRONG_INLINE int getBucket(const ChainActor * actor) const
|
||||||
{
|
{
|
||||||
|
@@ -131,11 +131,11 @@ namespace AIPathfinding
|
|||||||
{
|
{
|
||||||
AIPathNode * boatNode = boatNodeOptional.value();
|
AIPathNode * boatNode = boatNodeOptional.value();
|
||||||
|
|
||||||
if(boatNode->action == CGPathNode::UNKNOWN)
|
if(boatNode->action == EPathNodeAction::UNKNOWN)
|
||||||
{
|
{
|
||||||
boatNode->addSpecialAction(virtualBoat);
|
boatNode->addSpecialAction(virtualBoat);
|
||||||
destination.blocked = false;
|
destination.blocked = false;
|
||||||
destination.action = CGPathNode::ENodeAction::EMBARK;
|
destination.action = EPathNodeAction::EMBARK;
|
||||||
destination.node = boatNode;
|
destination.node = boatNode;
|
||||||
result = true;
|
result = true;
|
||||||
}
|
}
|
||||||
|
@@ -31,7 +31,7 @@ namespace AIPathfinding
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
if(blocker == BlockingReason::DESTINATION_BLOCKED
|
if(blocker == BlockingReason::DESTINATION_BLOCKED
|
||||||
&& destination.action == CGPathNode::EMBARK
|
&& destination.action == EPathNodeAction::EMBARK
|
||||||
&& nodeStorage->getAINode(destination.node)->specialAction)
|
&& nodeStorage->getAINode(destination.node)->specialAction)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
|
@@ -27,8 +27,8 @@ namespace AIPathfinding
|
|||||||
const PathfinderConfig * pathfinderConfig,
|
const PathfinderConfig * pathfinderConfig,
|
||||||
CPathfinderHelper * pathfinderHelper) const
|
CPathfinderHelper * pathfinderHelper) const
|
||||||
{
|
{
|
||||||
if(source.node->action == CGPathNode::ENodeAction::BLOCKING_VISIT
|
if(source.node->action == EPathNodeAction::BLOCKING_VISIT
|
||||||
|| source.node->action == CGPathNode::ENodeAction::VISIT)
|
|| source.node->action == EPathNodeAction::VISIT)
|
||||||
{
|
{
|
||||||
if(source.nodeObject
|
if(source.nodeObject
|
||||||
&& isObjectPassable(source.nodeObject, pathfinderHelper->hero->tempOwner, source.objectRelations))
|
&& isObjectPassable(source.nodeObject, pathfinderHelper->hero->tempOwner, source.objectRelations))
|
||||||
|
@@ -120,7 +120,7 @@ std::vector<CGPathNode *> AINodeStorage::getInitialNodes()
|
|||||||
return {initialNode};
|
return {initialNode};
|
||||||
}
|
}
|
||||||
|
|
||||||
void AINodeStorage::resetTile(const int3 & coord, EPathfindingLayer layer, CGPathNode::EAccessibility accessibility)
|
void AINodeStorage::resetTile(const int3 & coord, EPathfindingLayer layer, EPathAccessibility accessibility)
|
||||||
{
|
{
|
||||||
for(int i = 0; i < NUM_CHAINS; i++)
|
for(int i = 0; i < NUM_CHAINS; i++)
|
||||||
{
|
{
|
||||||
@@ -171,7 +171,7 @@ std::vector<CGPathNode *> AINodeStorage::calculateNeighbours(
|
|||||||
{
|
{
|
||||||
auto nextNode = getOrCreateNode(neighbour, i, srcNode->chainMask);
|
auto nextNode = getOrCreateNode(neighbour, i, srcNode->chainMask);
|
||||||
|
|
||||||
if(!nextNode || nextNode.value()->accessible == CGPathNode::NOT_SET)
|
if(!nextNode || nextNode.value()->accessible == EPathAccessibility::NOT_SET)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
neighbours.push_back(nextNode.value());
|
neighbours.push_back(nextNode.value());
|
||||||
@@ -294,7 +294,7 @@ bool AINodeStorage::hasBetterChain(const PathNodeInfo & source, CDestinationNode
|
|||||||
for(const AIPathNode & node : chains)
|
for(const AIPathNode & node : chains)
|
||||||
{
|
{
|
||||||
auto sameNode = node.chainMask == destinationNode->chainMask;
|
auto sameNode = node.chainMask == destinationNode->chainMask;
|
||||||
if(sameNode || node.action == CGPathNode::ENodeAction::UNKNOWN)
|
if(sameNode || node.action == EPathNodeAction::UNKNOWN)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -323,7 +323,7 @@ bool AINodeStorage::isTileAccessible(const int3 & pos, const EPathfindingLayer l
|
|||||||
{
|
{
|
||||||
const AIPathNode & node = nodes[layer][pos.z][pos.x][pos.y][0];
|
const AIPathNode & node = nodes[layer][pos.z][pos.x][pos.y][0];
|
||||||
|
|
||||||
return node.action != CGPathNode::ENodeAction::UNKNOWN;
|
return node.action != EPathNodeAction::UNKNOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<AIPath> AINodeStorage::getChainInfo(const int3 & pos, bool isOnLand) const
|
std::vector<AIPath> AINodeStorage::getChainInfo(const int3 & pos, bool isOnLand) const
|
||||||
@@ -334,7 +334,7 @@ std::vector<AIPath> AINodeStorage::getChainInfo(const int3 & pos, bool isOnLand)
|
|||||||
|
|
||||||
for(const AIPathNode & node : chains)
|
for(const AIPathNode & node : chains)
|
||||||
{
|
{
|
||||||
if(node.action == CGPathNode::ENodeAction::UNKNOWN)
|
if(node.action == EPathNodeAction::UNKNOWN)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@@ -70,7 +70,7 @@ private:
|
|||||||
std::unique_ptr<FuzzyHelper> dangerEvaluator;
|
std::unique_ptr<FuzzyHelper> dangerEvaluator;
|
||||||
|
|
||||||
STRONG_INLINE
|
STRONG_INLINE
|
||||||
void resetTile(const int3 & tile, EPathfindingLayer layer, CGPathNode::EAccessibility accessibility);
|
void resetTile(const int3 & tile, EPathfindingLayer layer, EPathAccessibility accessibility);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/// more than 1 chain layer allows us to have more than 1 path to each tile so we can chose more optimal one.
|
/// more than 1 chain layer allows us to have more than 1 path to each tile so we can chose more optimal one.
|
||||||
|
@@ -122,11 +122,11 @@ namespace AIPathfinding
|
|||||||
{
|
{
|
||||||
AIPathNode * boatNode = boatNodeOptional.value();
|
AIPathNode * boatNode = boatNodeOptional.value();
|
||||||
|
|
||||||
if(boatNode->action == CGPathNode::UNKNOWN)
|
if(boatNode->action == EPathNodeAction::UNKNOWN)
|
||||||
{
|
{
|
||||||
boatNode->specialAction = virtualBoat;
|
boatNode->specialAction = virtualBoat;
|
||||||
destination.blocked = false;
|
destination.blocked = false;
|
||||||
destination.action = CGPathNode::ENodeAction::EMBARK;
|
destination.action = EPathNodeAction::EMBARK;
|
||||||
destination.node = boatNode;
|
destination.node = boatNode;
|
||||||
result = true;
|
result = true;
|
||||||
}
|
}
|
||||||
|
@@ -29,7 +29,7 @@ namespace AIPathfinding
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
if(blocker == BlockingReason::DESTINATION_BLOCKED
|
if(blocker == BlockingReason::DESTINATION_BLOCKED
|
||||||
&& destination.action == CGPathNode::EMBARK
|
&& destination.action == EPathNodeAction::EMBARK
|
||||||
&& nodeStorage->getAINode(destination.node)->specialAction)
|
&& nodeStorage->getAINode(destination.node)->specialAction)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
|
@@ -23,7 +23,7 @@ namespace AIPathfinding
|
|||||||
const PathfinderConfig * pathfinderConfig,
|
const PathfinderConfig * pathfinderConfig,
|
||||||
CPathfinderHelper * pathfinderHelper) const
|
CPathfinderHelper * pathfinderHelper) const
|
||||||
{
|
{
|
||||||
if(source.node->action == CGPathNode::ENodeAction::BLOCKING_VISIT || source.node->action == CGPathNode::ENodeAction::VISIT)
|
if(source.node->action == EPathNodeAction::BLOCKING_VISIT || source.node->action == EPathNodeAction::VISIT)
|
||||||
{
|
{
|
||||||
// we can not directly bypass objects, we need to interact with them first
|
// we can not directly bypass objects, we need to interact with them first
|
||||||
destination.node->theNodeBefore = source.node;
|
destination.node->theNodeBefore = source.node;
|
||||||
|
@@ -1849,11 +1849,11 @@ bool VCAI::moveHeroToTile(int3 dst, HeroPtr h)
|
|||||||
//return cb->getTile(coord,false)->topVisitableObj(ignoreHero);
|
//return cb->getTile(coord,false)->topVisitableObj(ignoreHero);
|
||||||
};
|
};
|
||||||
|
|
||||||
auto isTeleportAction = [&](CGPathNode::ENodeAction action) -> bool
|
auto isTeleportAction = [&](EPathNodeAction action) -> bool
|
||||||
{
|
{
|
||||||
if(action != CGPathNode::TELEPORT_NORMAL && action != CGPathNode::TELEPORT_BLOCKING_VISIT)
|
if(action != EPathNodeAction::TELEPORT_NORMAL && action != EPathNodeAction::TELEPORT_BLOCKING_VISIT)
|
||||||
{
|
{
|
||||||
if(action != CGPathNode::TELEPORT_BATTLE)
|
if(action != EPathNodeAction::TELEPORT_BATTLE)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -1964,7 +1964,7 @@ bool VCAI::moveHeroToTile(int3 dst, HeroPtr h)
|
|||||||
doChannelProbing();
|
doChannelProbing();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(path.nodes[0].action == CGPathNode::BLOCKING_VISIT)
|
if(path.nodes[0].action == EPathNodeAction::BLOCKING_VISIT)
|
||||||
{
|
{
|
||||||
ret = h && i == 0; // when we take resource we do not reach its position. We even might not move
|
ret = h && i == 0; // when we take resource we do not reach its position. We even might not move
|
||||||
}
|
}
|
||||||
|
@@ -1884,11 +1884,11 @@ void CPlayerInterface::doMoveHero(const CGHeroInstance * h, CGPath path)
|
|||||||
return cb->getTile(h->convertToVisitablePos(coord))->topVisitableObj(ignoreHero);
|
return cb->getTile(h->convertToVisitablePos(coord))->topVisitableObj(ignoreHero);
|
||||||
};
|
};
|
||||||
|
|
||||||
auto isTeleportAction = [&](CGPathNode::ENodeAction action) -> bool
|
auto isTeleportAction = [&](EPathNodeAction action) -> bool
|
||||||
{
|
{
|
||||||
if (action != CGPathNode::TELEPORT_NORMAL &&
|
if (action != EPathNodeAction::TELEPORT_NORMAL &&
|
||||||
action != CGPathNode::TELEPORT_BLOCKING_VISIT &&
|
action != EPathNodeAction::TELEPORT_BLOCKING_VISIT &&
|
||||||
action != CGPathNode::TELEPORT_BATTLE)
|
action != EPathNodeAction::TELEPORT_BATTLE)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -1933,7 +1933,7 @@ void CPlayerInterface::doMoveHero(const CGHeroInstance * h, CGPath path)
|
|||||||
if (node->layer == EPathfindingLayer::LAND || node->layer == EPathfindingLayer::SAIL)
|
if (node->layer == EPathfindingLayer::LAND || node->layer == EPathfindingLayer::SAIL)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (node->accessible == CGPathNode::ACCESSIBLE)
|
if (node->accessible == EPathAccessibility::ACCESSIBLE)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@@ -1959,8 +1959,8 @@ void CPlayerInterface::doMoveHero(const CGHeroInstance * h, CGPath path)
|
|||||||
destinationTeleport = destTeleportObj->id;
|
destinationTeleport = destTeleportObj->id;
|
||||||
destinationTeleportPos = nextCoord;
|
destinationTeleportPos = nextCoord;
|
||||||
doMovement(h->pos, false);
|
doMovement(h->pos, false);
|
||||||
if (path.nodes[i-1].action == CGPathNode::TELEPORT_BLOCKING_VISIT
|
if (path.nodes[i-1].action == EPathNodeAction::TELEPORT_BLOCKING_VISIT
|
||||||
|| path.nodes[i-1].action == CGPathNode::TELEPORT_BATTLE)
|
|| path.nodes[i-1].action == EPathNodeAction::TELEPORT_BATTLE)
|
||||||
{
|
{
|
||||||
destinationTeleport = ObjectInstanceID();
|
destinationTeleport = ObjectInstanceID();
|
||||||
destinationTeleportPos = int3(-1);
|
destinationTeleportPos = int3(-1);
|
||||||
|
@@ -615,17 +615,17 @@ void AdventureMapInterface::onTileHovered(const int3 &mapPos)
|
|||||||
vstd::amin(turns, 3);
|
vstd::amin(turns, 3);
|
||||||
switch(pathNode->action)
|
switch(pathNode->action)
|
||||||
{
|
{
|
||||||
case CGPathNode::NORMAL:
|
case EPathNodeAction::NORMAL:
|
||||||
case CGPathNode::TELEPORT_NORMAL:
|
case EPathNodeAction::TELEPORT_NORMAL:
|
||||||
if(pathNode->layer == EPathfindingLayer::LAND)
|
if(pathNode->layer == EPathfindingLayer::LAND)
|
||||||
CCS->curh->set(cursorMove[turns]);
|
CCS->curh->set(cursorMove[turns]);
|
||||||
else
|
else
|
||||||
CCS->curh->set(cursorSailVisit[turns]);
|
CCS->curh->set(cursorSailVisit[turns]);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CGPathNode::VISIT:
|
case EPathNodeAction::VISIT:
|
||||||
case CGPathNode::BLOCKING_VISIT:
|
case EPathNodeAction::BLOCKING_VISIT:
|
||||||
case CGPathNode::TELEPORT_BLOCKING_VISIT:
|
case EPathNodeAction::TELEPORT_BLOCKING_VISIT:
|
||||||
if(objAtTile && objAtTile->ID == Obj::HERO)
|
if(objAtTile && objAtTile->ID == Obj::HERO)
|
||||||
{
|
{
|
||||||
if(LOCPLINT->localState->getCurrentArmy() == objAtTile)
|
if(LOCPLINT->localState->getCurrentArmy() == objAtTile)
|
||||||
@@ -639,16 +639,16 @@ void AdventureMapInterface::onTileHovered(const int3 &mapPos)
|
|||||||
CCS->curh->set(cursorSailVisit[turns]);
|
CCS->curh->set(cursorSailVisit[turns]);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CGPathNode::BATTLE:
|
case EPathNodeAction::BATTLE:
|
||||||
case CGPathNode::TELEPORT_BATTLE:
|
case EPathNodeAction::TELEPORT_BATTLE:
|
||||||
CCS->curh->set(cursorAttack[turns]);
|
CCS->curh->set(cursorAttack[turns]);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CGPathNode::EMBARK:
|
case EPathNodeAction::EMBARK:
|
||||||
CCS->curh->set(cursorSail[turns]);
|
CCS->curh->set(cursorSail[turns]);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CGPathNode::DISEMBARK:
|
case EPathNodeAction::DISEMBARK:
|
||||||
CCS->curh->set(cursorDisembark[turns]);
|
CCS->curh->set(cursorDisembark[turns]);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@@ -714,7 +714,7 @@ size_t MapRendererPath::selectImage(IMapRendererContext & context, const int3 &
|
|||||||
return std::numeric_limits<size_t>::max();
|
return std::numeric_limits<size_t>::max();
|
||||||
|
|
||||||
bool pathContinuous = iter->coord.areNeighbours(next->coord) && iter->coord.areNeighbours(prev->coord);
|
bool pathContinuous = iter->coord.areNeighbours(next->coord) && iter->coord.areNeighbours(prev->coord);
|
||||||
bool embarking = iter->action == CGPathNode::EMBARK || iter->action == CGPathNode::DISEMBARK;
|
bool embarking = iter->action == EPathNodeAction::EMBARK || iter->action == EPathNodeAction::DISEMBARK;
|
||||||
|
|
||||||
if(pathContinuous && !embarking)
|
if(pathContinuous && !embarking)
|
||||||
return selectImageArrow(reachableToday, iter->coord, prev->coord, next->coord);
|
return selectImageArrow(reachableToday, iter->coord, prev->coord, next->coord);
|
||||||
|
@@ -138,7 +138,7 @@ bool PathNodeInfo::isNodeObjectVisitable() const
|
|||||||
|
|
||||||
CDestinationNodeInfo::CDestinationNodeInfo():
|
CDestinationNodeInfo::CDestinationNodeInfo():
|
||||||
blocked(false),
|
blocked(false),
|
||||||
action(CGPathNode::ENodeAction::UNKNOWN)
|
action(EPathNodeAction::UNKNOWN)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -147,7 +147,7 @@ void CDestinationNodeInfo::setNode(CGameState * gs, CGPathNode * n)
|
|||||||
PathNodeInfo::setNode(gs, n);
|
PathNodeInfo::setNode(gs, n);
|
||||||
|
|
||||||
blocked = false;
|
blocked = false;
|
||||||
action = CGPathNode::ENodeAction::UNKNOWN;
|
action = EPathNodeAction::UNKNOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CDestinationNodeInfo::isBetterWay() const
|
bool CDestinationNodeInfo::isBetterWay() const
|
||||||
|
@@ -32,42 +32,42 @@ struct DLL_LINKAGE NodeComparer
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum class EPathAccessibility : ui8
|
||||||
|
{
|
||||||
|
NOT_SET,
|
||||||
|
ACCESSIBLE, //tile can be entered and passed
|
||||||
|
VISITABLE, //tile can be entered as the last tile in path
|
||||||
|
BLOCKVIS, //visitable from neighboring tile but not passable
|
||||||
|
FLYABLE, //can only be accessed in air layer
|
||||||
|
BLOCKED //tile can be neither entered nor visited
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class EPathNodeAction : ui8
|
||||||
|
{
|
||||||
|
UNKNOWN,
|
||||||
|
EMBARK,
|
||||||
|
DISEMBARK,
|
||||||
|
NORMAL,
|
||||||
|
BATTLE,
|
||||||
|
VISIT,
|
||||||
|
BLOCKING_VISIT,
|
||||||
|
TELEPORT_NORMAL,
|
||||||
|
TELEPORT_BLOCKING_VISIT,
|
||||||
|
TELEPORT_BATTLE
|
||||||
|
};
|
||||||
|
|
||||||
struct DLL_LINKAGE CGPathNode
|
struct DLL_LINKAGE CGPathNode
|
||||||
{
|
{
|
||||||
using ELayer = EPathfindingLayer;
|
using ELayer = EPathfindingLayer;
|
||||||
|
|
||||||
enum ENodeAction : ui8
|
|
||||||
{
|
|
||||||
UNKNOWN = 0,
|
|
||||||
EMBARK = 1,
|
|
||||||
DISEMBARK,
|
|
||||||
NORMAL,
|
|
||||||
BATTLE,
|
|
||||||
VISIT,
|
|
||||||
BLOCKING_VISIT,
|
|
||||||
TELEPORT_NORMAL,
|
|
||||||
TELEPORT_BLOCKING_VISIT,
|
|
||||||
TELEPORT_BATTLE
|
|
||||||
};
|
|
||||||
|
|
||||||
enum EAccessibility : ui8
|
|
||||||
{
|
|
||||||
NOT_SET = 0,
|
|
||||||
ACCESSIBLE = 1, //tile can be entered and passed
|
|
||||||
VISITABLE, //tile can be entered as the last tile in path
|
|
||||||
BLOCKVIS, //visitable from neighboring tile but not passable
|
|
||||||
FLYABLE, //can only be accessed in air layer
|
|
||||||
BLOCKED //tile can be neither entered nor visited
|
|
||||||
};
|
|
||||||
|
|
||||||
CGPathNode * theNodeBefore;
|
CGPathNode * theNodeBefore;
|
||||||
int3 coord; //coordinates
|
int3 coord; //coordinates
|
||||||
ELayer layer;
|
ELayer layer;
|
||||||
ui32 moveRemains; //remaining movement points after hero reaches the tile
|
ui32 moveRemains; //remaining movement points after hero reaches the tile
|
||||||
ui8 turns; //how many turns we have to wait before reaching the tile - 0 means current turn
|
ui8 turns; //how many turns we have to wait before reaching the tile - 0 means current turn
|
||||||
|
|
||||||
EAccessibility accessible;
|
EPathAccessibility accessible;
|
||||||
ENodeAction action;
|
EPathNodeAction action;
|
||||||
bool locked;
|
bool locked;
|
||||||
bool inPQ;
|
bool inPQ;
|
||||||
|
|
||||||
@@ -83,12 +83,12 @@ struct DLL_LINKAGE CGPathNode
|
|||||||
void reset()
|
void reset()
|
||||||
{
|
{
|
||||||
locked = false;
|
locked = false;
|
||||||
accessible = NOT_SET;
|
accessible = EPathAccessibility::NOT_SET;
|
||||||
moveRemains = 0;
|
moveRemains = 0;
|
||||||
cost = std::numeric_limits<float>::max();
|
cost = std::numeric_limits<float>::max();
|
||||||
turns = 255;
|
turns = 255;
|
||||||
theNodeBefore = nullptr;
|
theNodeBefore = nullptr;
|
||||||
action = UNKNOWN;
|
action = EPathNodeAction::UNKNOWN;
|
||||||
inPQ = false;
|
inPQ = false;
|
||||||
pq = nullptr;
|
pq = nullptr;
|
||||||
}
|
}
|
||||||
@@ -122,7 +122,7 @@ struct DLL_LINKAGE CGPathNode
|
|||||||
}
|
}
|
||||||
|
|
||||||
STRONG_INLINE
|
STRONG_INLINE
|
||||||
void update(const int3 & Coord, const ELayer Layer, const EAccessibility Accessible)
|
void update(const int3 & Coord, const ELayer Layer, const EPathAccessibility Accessible)
|
||||||
{
|
{
|
||||||
if(layer == ELayer::WRONG)
|
if(layer == ELayer::WRONG)
|
||||||
{
|
{
|
||||||
@@ -205,7 +205,7 @@ struct DLL_LINKAGE PathNodeInfo
|
|||||||
|
|
||||||
struct DLL_LINKAGE CDestinationNodeInfo : public PathNodeInfo
|
struct DLL_LINKAGE CDestinationNodeInfo : public PathNodeInfo
|
||||||
{
|
{
|
||||||
CGPathNode::ENodeAction action;
|
EPathNodeAction action;
|
||||||
int turn;
|
int turn;
|
||||||
int movementLeft;
|
int movementLeft;
|
||||||
float cost; //same as CGPathNode::cost
|
float cost; //same as CGPathNode::cost
|
||||||
|
@@ -183,7 +183,7 @@ void CPathfinder::calculatePaths()
|
|||||||
/// Objects are usually visible on FoW border anyway so it's not cheating.
|
/// Objects are usually visible on FoW border anyway so it's not cheating.
|
||||||
///
|
///
|
||||||
/// For now it's disabled as it's will cause crashes in movement code.
|
/// For now it's disabled as it's will cause crashes in movement code.
|
||||||
if(teleportNode->accessible == CGPathNode::BLOCKED)
|
if(teleportNode->accessible == EPathAccessibility::BLOCKED)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
destination.setNode(gamestate, teleportNode);
|
destination.setNode(gamestate, teleportNode);
|
||||||
@@ -196,7 +196,7 @@ void CPathfinder::calculatePaths()
|
|||||||
destination.action = getTeleportDestAction();
|
destination.action = getTeleportDestAction();
|
||||||
config->nodeStorage->commit(destination, source);
|
config->nodeStorage->commit(destination, source);
|
||||||
|
|
||||||
if(destination.node->action == CGPathNode::TELEPORT_NORMAL)
|
if(destination.node->action == EPathNodeAction::TELEPORT_NORMAL)
|
||||||
push(destination.node);
|
push(destination.node);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -293,7 +293,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 == CGPathNode::BATTLE)
|
if(source.node->action == EPathNodeAction::BATTLE)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
switch(source.node->layer)
|
switch(source.node->layer)
|
||||||
@@ -336,16 +336,16 @@ bool CPathfinder::isLayerTransitionPossible() const
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
CGPathNode::ENodeAction CPathfinder::getTeleportDestAction() const
|
EPathNodeAction CPathfinder::getTeleportDestAction() const
|
||||||
{
|
{
|
||||||
CGPathNode::ENodeAction action = CGPathNode::TELEPORT_NORMAL;
|
EPathNodeAction action = EPathNodeAction::TELEPORT_NORMAL;
|
||||||
|
|
||||||
if(destination.isNodeObjectVisitable() && destination.nodeHero)
|
if(destination.isNodeObjectVisitable() && destination.nodeHero)
|
||||||
{
|
{
|
||||||
if(destination.heroRelations == PlayerRelations::ENEMIES)
|
if(destination.heroRelations == PlayerRelations::ENEMIES)
|
||||||
action = CGPathNode::TELEPORT_BATTLE;
|
action = EPathNodeAction::TELEPORT_BATTLE;
|
||||||
else
|
else
|
||||||
action = CGPathNode::TELEPORT_BLOCKING_VISIT;
|
action = EPathNodeAction::TELEPORT_BLOCKING_VISIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
return action;
|
return action;
|
||||||
@@ -449,7 +449,7 @@ bool CPathfinderHelper::passOneTurnLimitCheck(const PathNodeInfo & source) const
|
|||||||
return false;
|
return false;
|
||||||
if(source.node->layer == EPathfindingLayer::AIR)
|
if(source.node->layer == EPathfindingLayer::AIR)
|
||||||
{
|
{
|
||||||
return options.originalMovementRules && source.node->accessible == CGPathNode::ACCESSIBLE;
|
return options.originalMovementRules && source.node->accessible == EPathAccessibility::ACCESSIBLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@@ -43,7 +43,7 @@ private:
|
|||||||
CDestinationNodeInfo destination; //destination node -> it's a neighbour of source that we consider
|
CDestinationNodeInfo destination; //destination node -> it's a neighbour of source that we consider
|
||||||
|
|
||||||
bool isLayerTransitionPossible() const;
|
bool isLayerTransitionPossible() const;
|
||||||
CGPathNode::ENodeAction getTeleportDestAction() const;
|
EPathNodeAction getTeleportDestAction() const;
|
||||||
|
|
||||||
bool isDestinationGuardian() const;
|
bool isDestinationGuardian() const;
|
||||||
|
|
||||||
|
@@ -74,7 +74,7 @@ std::vector<CGPathNode *> NodeStorage::calculateNeighbours(
|
|||||||
{
|
{
|
||||||
auto * node = getNode(neighbour, i);
|
auto * node = getNode(neighbour, i);
|
||||||
|
|
||||||
if(node->accessible == CGPathNode::NOT_SET)
|
if(node->accessible == EPathAccessibility::NOT_SET)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
neighbours.push_back(node);
|
neighbours.push_back(node);
|
||||||
@@ -113,7 +113,7 @@ NodeStorage::NodeStorage(CPathsInfo & pathsInfo, const CGHeroInstance * hero)
|
|||||||
out.hpos = hero->visitablePos();
|
out.hpos = hero->visitablePos();
|
||||||
}
|
}
|
||||||
|
|
||||||
void NodeStorage::resetTile(const int3 & tile, const EPathfindingLayer & layer, CGPathNode::EAccessibility accessibility)
|
void NodeStorage::resetTile(const int3 & tile, const EPathfindingLayer & layer, EPathAccessibility accessibility)
|
||||||
{
|
{
|
||||||
getNode(tile, layer)->update(tile, layer, accessibility);
|
getNode(tile, layer)->update(tile, layer, accessibility);
|
||||||
}
|
}
|
||||||
|
@@ -20,7 +20,7 @@ private:
|
|||||||
CPathsInfo & out;
|
CPathsInfo & out;
|
||||||
|
|
||||||
STRONG_INLINE
|
STRONG_INLINE
|
||||||
void resetTile(const int3 & tile, const EPathfindingLayer & layer, CGPathNode::EAccessibility accessibility);
|
void resetTile(const int3 & tile, const EPathfindingLayer & layer, EPathAccessibility accessibility);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
NodeStorage(CPathsInfo & pathsInfo, const CGHeroInstance * hero);
|
NodeStorage(CPathsInfo & pathsInfo, const CGHeroInstance * hero);
|
||||||
|
@@ -13,6 +13,7 @@
|
|||||||
#include "../mapObjects/CGObjectInstance.h"
|
#include "../mapObjects/CGObjectInstance.h"
|
||||||
#include "../mapping/CMapDefines.h"
|
#include "../mapping/CMapDefines.h"
|
||||||
#include "../CGameState.h"
|
#include "../CGameState.h"
|
||||||
|
#include "CGPathNode.h"
|
||||||
|
|
||||||
VCMI_LIB_NAMESPACE_BEGIN
|
VCMI_LIB_NAMESPACE_BEGIN
|
||||||
|
|
||||||
@@ -22,10 +23,10 @@ namespace PathfinderUtil
|
|||||||
using ELayer = EPathfindingLayer;
|
using ELayer = EPathfindingLayer;
|
||||||
|
|
||||||
template<EPathfindingLayer::EEPathfindingLayer layer>
|
template<EPathfindingLayer::EEPathfindingLayer layer>
|
||||||
CGPathNode::EAccessibility evaluateAccessibility(const int3 & pos, const TerrainTile & tinfo, FoW fow, const PlayerColor player, const CGameState * gs)
|
EPathAccessibility evaluateAccessibility(const int3 & pos, const TerrainTile & tinfo, FoW fow, const PlayerColor player, const CGameState * gs)
|
||||||
{
|
{
|
||||||
if(!(*fow)[pos.z][pos.x][pos.y])
|
if(!(*fow)[pos.z][pos.x][pos.y])
|
||||||
return CGPathNode::BLOCKED;
|
return EPathAccessibility::BLOCKED;
|
||||||
|
|
||||||
switch(layer)
|
switch(layer)
|
||||||
{
|
{
|
||||||
@@ -35,47 +36,47 @@ namespace PathfinderUtil
|
|||||||
{
|
{
|
||||||
if(tinfo.visitableObjects.front()->ID == Obj::SANCTUARY && tinfo.visitableObjects.back()->ID == Obj::HERO && tinfo.visitableObjects.back()->tempOwner != player) //non-owned hero stands on Sanctuary
|
if(tinfo.visitableObjects.front()->ID == Obj::SANCTUARY && tinfo.visitableObjects.back()->ID == Obj::HERO && tinfo.visitableObjects.back()->tempOwner != player) //non-owned hero stands on Sanctuary
|
||||||
{
|
{
|
||||||
return CGPathNode::BLOCKED;
|
return EPathAccessibility::BLOCKED;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for(const CGObjectInstance * obj : tinfo.visitableObjects)
|
for(const CGObjectInstance * obj : tinfo.visitableObjects)
|
||||||
{
|
{
|
||||||
if(obj->blockVisit)
|
if(obj->blockVisit)
|
||||||
return CGPathNode::BLOCKVIS;
|
return EPathAccessibility::BLOCKVIS;
|
||||||
else if(obj->passableFor(player))
|
else if(obj->passableFor(player))
|
||||||
return CGPathNode::ACCESSIBLE;
|
return EPathAccessibility::ACCESSIBLE;
|
||||||
else if(obj->ID != Obj::EVENT)
|
else if(obj->ID != Obj::EVENT)
|
||||||
return CGPathNode::VISITABLE;
|
return EPathAccessibility::VISITABLE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(tinfo.blocked)
|
else if(tinfo.blocked)
|
||||||
{
|
{
|
||||||
return CGPathNode::BLOCKED;
|
return EPathAccessibility::BLOCKED;
|
||||||
}
|
}
|
||||||
else if(gs->guardingCreaturePosition(pos).valid())
|
else if(gs->guardingCreaturePosition(pos).valid())
|
||||||
{
|
{
|
||||||
// Monster close by; blocked visit for battle
|
// Monster close by; blocked visit for battle
|
||||||
return CGPathNode::BLOCKVIS;
|
return EPathAccessibility::BLOCKVIS;
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ELayer::WATER:
|
case ELayer::WATER:
|
||||||
if(tinfo.blocked || tinfo.terType->isLand())
|
if(tinfo.blocked || tinfo.terType->isLand())
|
||||||
return CGPathNode::BLOCKED;
|
return EPathAccessibility::BLOCKED;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ELayer::AIR:
|
case ELayer::AIR:
|
||||||
if(tinfo.blocked || tinfo.terType->isLand())
|
if(tinfo.blocked || tinfo.terType->isLand())
|
||||||
return CGPathNode::FLYABLE;
|
return EPathAccessibility::FLYABLE;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return CGPathNode::ACCESSIBLE;
|
return EPathAccessibility::ACCESSIBLE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -48,11 +48,11 @@ void MovementCostRule::process(
|
|||||||
remains = moveAtNextTile - cost;
|
remains = moveAtNextTile - cost;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(destination.action == CGPathNode::EMBARK || destination.action == CGPathNode::DISEMBARK)
|
if(destination.action == EPathNodeAction::EMBARK || destination.action == EPathNodeAction::DISEMBARK)
|
||||||
{
|
{
|
||||||
/// FREE_SHIP_BOARDING bonus only remove additional penalty
|
/// FREE_SHIP_BOARDING bonus only remove additional penalty
|
||||||
/// land <-> sail transition still cost movement points as normal movement
|
/// land <-> sail transition still cost movement points as normal movement
|
||||||
remains = pathfinderHelper->movementPointsAfterEmbark(moveAtNextTile, cost, (destination.action == CGPathNode::DISEMBARK));
|
remains = pathfinderHelper->movementPointsAfterEmbark(moveAtNextTile, cost, (destination.action == EPathNodeAction::DISEMBARK));
|
||||||
cost = moveAtNextTile - remains;
|
cost = moveAtNextTile - remains;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -90,7 +90,7 @@ void DestinationActionRule::process(
|
|||||||
const PathfinderConfig * pathfinderConfig,
|
const PathfinderConfig * pathfinderConfig,
|
||||||
CPathfinderHelper * pathfinderHelper) const
|
CPathfinderHelper * pathfinderHelper) const
|
||||||
{
|
{
|
||||||
if(destination.action != CGPathNode::ENodeAction::UNKNOWN)
|
if(destination.action != EPathNodeAction::UNKNOWN)
|
||||||
{
|
{
|
||||||
#ifdef VCMI_TRACE_PATHFINDER
|
#ifdef VCMI_TRACE_PATHFINDER
|
||||||
logAi->trace("Accepted precalculated action at %s", destination.coord.toString());
|
logAi->trace("Accepted precalculated action at %s", destination.coord.toString());
|
||||||
@@ -98,7 +98,7 @@ void DestinationActionRule::process(
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
CGPathNode::ENodeAction action = CGPathNode::NORMAL;
|
EPathNodeAction action = EPathNodeAction::NORMAL;
|
||||||
const auto * hero = pathfinderHelper->hero;
|
const auto * hero = pathfinderHelper->hero;
|
||||||
|
|
||||||
switch(destination.node->layer)
|
switch(destination.node->layer)
|
||||||
@@ -107,7 +107,7 @@ void DestinationActionRule::process(
|
|||||||
if(source.node->layer == EPathfindingLayer::SAIL)
|
if(source.node->layer == EPathfindingLayer::SAIL)
|
||||||
{
|
{
|
||||||
// TODO: Handle dismebark into guarded areaa
|
// TODO: Handle dismebark into guarded areaa
|
||||||
action = CGPathNode::DISEMBARK;
|
action = EPathNodeAction::DISEMBARK;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -120,56 +120,56 @@ void DestinationActionRule::process(
|
|||||||
auto objRel = destination.objectRelations;
|
auto objRel = destination.objectRelations;
|
||||||
|
|
||||||
if(destination.nodeObject->ID == Obj::BOAT)
|
if(destination.nodeObject->ID == Obj::BOAT)
|
||||||
action = CGPathNode::EMBARK;
|
action = EPathNodeAction::EMBARK;
|
||||||
else if(destination.nodeHero)
|
else if(destination.nodeHero)
|
||||||
{
|
{
|
||||||
if(destination.heroRelations == PlayerRelations::ENEMIES)
|
if(destination.heroRelations == PlayerRelations::ENEMIES)
|
||||||
action = CGPathNode::BATTLE;
|
action = EPathNodeAction::BATTLE;
|
||||||
else
|
else
|
||||||
action = CGPathNode::BLOCKING_VISIT;
|
action = EPathNodeAction::BLOCKING_VISIT;
|
||||||
}
|
}
|
||||||
else if(destination.nodeObject->ID == Obj::TOWN)
|
else if(destination.nodeObject->ID == Obj::TOWN)
|
||||||
{
|
{
|
||||||
if(destination.nodeObject->passableFor(hero->tempOwner))
|
if(destination.nodeObject->passableFor(hero->tempOwner))
|
||||||
action = CGPathNode::VISIT;
|
action = EPathNodeAction::VISIT;
|
||||||
else if(objRel == PlayerRelations::ENEMIES)
|
else if(objRel == PlayerRelations::ENEMIES)
|
||||||
action = CGPathNode::BATTLE;
|
action = EPathNodeAction::BATTLE;
|
||||||
}
|
}
|
||||||
else if(destination.nodeObject->ID == Obj::GARRISON || destination.nodeObject->ID == Obj::GARRISON2)
|
else if(destination.nodeObject->ID == Obj::GARRISON || destination.nodeObject->ID == Obj::GARRISON2)
|
||||||
{
|
{
|
||||||
if(destination.nodeObject->passableFor(hero->tempOwner))
|
if(destination.nodeObject->passableFor(hero->tempOwner))
|
||||||
{
|
{
|
||||||
if(destination.guarded)
|
if(destination.guarded)
|
||||||
action = CGPathNode::BATTLE;
|
action = EPathNodeAction::BATTLE;
|
||||||
}
|
}
|
||||||
else if(objRel == PlayerRelations::ENEMIES)
|
else if(objRel == PlayerRelations::ENEMIES)
|
||||||
action = CGPathNode::BATTLE;
|
action = EPathNodeAction::BATTLE;
|
||||||
}
|
}
|
||||||
else if(destination.nodeObject->ID == Obj::BORDER_GATE)
|
else if(destination.nodeObject->ID == Obj::BORDER_GATE)
|
||||||
{
|
{
|
||||||
if(destination.nodeObject->passableFor(hero->tempOwner))
|
if(destination.nodeObject->passableFor(hero->tempOwner))
|
||||||
{
|
{
|
||||||
if(destination.guarded)
|
if(destination.guarded)
|
||||||
action = CGPathNode::BATTLE;
|
action = EPathNodeAction::BATTLE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
action = CGPathNode::BLOCKING_VISIT;
|
action = EPathNodeAction::BLOCKING_VISIT;
|
||||||
}
|
}
|
||||||
else if(destination.isGuardianTile)
|
else if(destination.isGuardianTile)
|
||||||
action = CGPathNode::BATTLE;
|
action = EPathNodeAction::BATTLE;
|
||||||
else if(destination.nodeObject->blockVisit && !(pathfinderConfig->options.useCastleGate && destination.nodeObject->ID == Obj::TOWN))
|
else if(destination.nodeObject->blockVisit && !(pathfinderConfig->options.useCastleGate && destination.nodeObject->ID == Obj::TOWN))
|
||||||
action = CGPathNode::BLOCKING_VISIT;
|
action = EPathNodeAction::BLOCKING_VISIT;
|
||||||
|
|
||||||
if(action == CGPathNode::NORMAL)
|
if(action == EPathNodeAction::NORMAL)
|
||||||
{
|
{
|
||||||
if(destination.guarded)
|
if(destination.guarded)
|
||||||
action = CGPathNode::BATTLE;
|
action = EPathNodeAction::BATTLE;
|
||||||
else
|
else
|
||||||
action = CGPathNode::VISIT;
|
action = EPathNodeAction::VISIT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(destination.guarded)
|
else if(destination.guarded)
|
||||||
action = CGPathNode::BATTLE;
|
action = EPathNodeAction::BATTLE;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -185,7 +185,7 @@ void MovementAfterDestinationRule::process(
|
|||||||
{
|
{
|
||||||
auto blocker = getBlockingReason(source, destination, config, pathfinderHelper);
|
auto blocker = getBlockingReason(source, destination, config, pathfinderHelper);
|
||||||
|
|
||||||
if(blocker == BlockingReason::DESTINATION_GUARDED && destination.action == CGPathNode::ENodeAction::BATTLE)
|
if(blocker == BlockingReason::DESTINATION_GUARDED && destination.action == EPathNodeAction::BATTLE)
|
||||||
{
|
{
|
||||||
return; // allow bypass guarded tile but only in direction of guard, a bit UI related thing
|
return; // allow bypass guarded tile but only in direction of guard, a bit UI related thing
|
||||||
}
|
}
|
||||||
@@ -204,7 +204,7 @@ PathfinderBlockingRule::BlockingReason MovementAfterDestinationRule::getBlocking
|
|||||||
{
|
{
|
||||||
/// TODO: Investigate what kind of limitation is possible to apply on movement from visitable tiles
|
/// TODO: Investigate what kind of limitation is possible to apply on movement from visitable tiles
|
||||||
/// Likely in many cases we don't need to add visitable tile to queue when hero doesn't fly
|
/// Likely in many cases we don't need to add visitable tile to queue when hero doesn't fly
|
||||||
case CGPathNode::VISIT:
|
case EPathNodeAction::VISIT:
|
||||||
{
|
{
|
||||||
/// For now we only add visitable tile into queue when it's teleporter that allow transit
|
/// For now we only add visitable tile into queue when it's teleporter that allow transit
|
||||||
/// Movement from visitable tile when hero is standing on it is possible into any layer
|
/// Movement from visitable tile when hero is standing on it is possible into any layer
|
||||||
@@ -226,27 +226,27 @@ PathfinderBlockingRule::BlockingReason MovementAfterDestinationRule::getBlocking
|
|||||||
return BlockingReason::DESTINATION_VISIT;
|
return BlockingReason::DESTINATION_VISIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
case CGPathNode::BLOCKING_VISIT:
|
case EPathNodeAction::BLOCKING_VISIT:
|
||||||
return destination.guarded
|
return destination.guarded
|
||||||
? BlockingReason::DESTINATION_GUARDED
|
? BlockingReason::DESTINATION_GUARDED
|
||||||
: BlockingReason::DESTINATION_BLOCKVIS;
|
: BlockingReason::DESTINATION_BLOCKVIS;
|
||||||
|
|
||||||
case CGPathNode::NORMAL:
|
case EPathNodeAction::NORMAL:
|
||||||
return BlockingReason::NONE;
|
return BlockingReason::NONE;
|
||||||
|
|
||||||
case CGPathNode::EMBARK:
|
case EPathNodeAction::EMBARK:
|
||||||
if(pathfinderHelper->options.useEmbarkAndDisembark)
|
if(pathfinderHelper->options.useEmbarkAndDisembark)
|
||||||
return BlockingReason::NONE;
|
return BlockingReason::NONE;
|
||||||
|
|
||||||
return BlockingReason::DESTINATION_BLOCKED;
|
return BlockingReason::DESTINATION_BLOCKED;
|
||||||
|
|
||||||
case CGPathNode::DISEMBARK:
|
case EPathNodeAction::DISEMBARK:
|
||||||
if(pathfinderHelper->options.useEmbarkAndDisembark)
|
if(pathfinderHelper->options.useEmbarkAndDisembark)
|
||||||
return destination.guarded ? BlockingReason::DESTINATION_GUARDED : BlockingReason::NONE;
|
return destination.guarded ? BlockingReason::DESTINATION_GUARDED : BlockingReason::NONE;
|
||||||
|
|
||||||
return BlockingReason::DESTINATION_BLOCKED;
|
return BlockingReason::DESTINATION_BLOCKED;
|
||||||
|
|
||||||
case CGPathNode::BATTLE:
|
case EPathNodeAction::BATTLE:
|
||||||
/// Movement after BATTLE action only possible from guarded tile to guardian tile
|
/// Movement after BATTLE action only possible from guarded tile to guardian tile
|
||||||
if(destination.guarded)
|
if(destination.guarded)
|
||||||
return BlockingReason::DESTINATION_GUARDED;
|
return BlockingReason::DESTINATION_GUARDED;
|
||||||
@@ -265,7 +265,7 @@ PathfinderBlockingRule::BlockingReason MovementToDestinationRule::getBlockingRea
|
|||||||
const CPathfinderHelper * pathfinderHelper) const
|
const CPathfinderHelper * pathfinderHelper) const
|
||||||
{
|
{
|
||||||
|
|
||||||
if(destination.node->accessible == CGPathNode::BLOCKED)
|
if(destination.node->accessible == EPathAccessibility::BLOCKED)
|
||||||
return BlockingReason::DESTINATION_BLOCKED;
|
return BlockingReason::DESTINATION_BLOCKED;
|
||||||
|
|
||||||
switch(destination.node->layer)
|
switch(destination.node->layer)
|
||||||
@@ -292,7 +292,7 @@ PathfinderBlockingRule::BlockingReason MovementToDestinationRule::getBlockingRea
|
|||||||
if(source.guarded)
|
if(source.guarded)
|
||||||
{
|
{
|
||||||
// Hero embarked a boat standing on a guarded tile -> we must allow to move away from that tile
|
// Hero embarked a boat standing on a guarded tile -> we must allow to move away from that tile
|
||||||
if(source.node->action != CGPathNode::EMBARK && !destination.isGuardianTile)
|
if(source.node->action != EPathNodeAction::EMBARK && !destination.isGuardianTile)
|
||||||
return BlockingReason::SOURCE_GUARDED;
|
return BlockingReason::SOURCE_GUARDED;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -314,7 +314,7 @@ PathfinderBlockingRule::BlockingReason MovementToDestinationRule::getBlockingRea
|
|||||||
|
|
||||||
case EPathfindingLayer::WATER:
|
case EPathfindingLayer::WATER:
|
||||||
if(!pathfinderHelper->canMoveBetween(source.coord, destination.coord)
|
if(!pathfinderHelper->canMoveBetween(source.coord, destination.coord)
|
||||||
|| destination.node->accessible != CGPathNode::ACCESSIBLE)
|
|| destination.node->accessible != EPathAccessibility::ACCESSIBLE)
|
||||||
{
|
{
|
||||||
return BlockingReason::DESTINATION_BLOCKED;
|
return BlockingReason::DESTINATION_BLOCKED;
|
||||||
}
|
}
|
||||||
@@ -343,7 +343,7 @@ void LayerTransitionRule::process(
|
|||||||
if(destination.node->layer == EPathfindingLayer::SAIL)
|
if(destination.node->layer == EPathfindingLayer::SAIL)
|
||||||
{
|
{
|
||||||
/// Cannot enter empty water tile from land -> it has to be visitable
|
/// Cannot enter empty water tile from land -> it has to be visitable
|
||||||
if(destination.node->accessible == CGPathNode::ACCESSIBLE)
|
if(destination.node->accessible == EPathAccessibility::ACCESSIBLE)
|
||||||
destination.blocked = true;
|
destination.blocked = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -351,7 +351,7 @@ void LayerTransitionRule::process(
|
|||||||
|
|
||||||
case EPathfindingLayer::SAIL:
|
case EPathfindingLayer::SAIL:
|
||||||
//tile must be accessible -> exception: unblocked blockvis tiles -> clear but guarded by nearby monster coast
|
//tile must be accessible -> exception: unblocked blockvis tiles -> clear but guarded by nearby monster coast
|
||||||
if((destination.node->accessible != CGPathNode::ACCESSIBLE && (destination.node->accessible != CGPathNode::BLOCKVIS || destination.tile->blocked))
|
if((destination.node->accessible != EPathAccessibility::ACCESSIBLE && (destination.node->accessible != EPathAccessibility::BLOCKVIS || destination.tile->blocked))
|
||||||
|| destination.tile->visitable) //TODO: passableness problem -> town says it's passable (thus accessible) but we obviously can't disembark onto town gate
|
|| destination.tile->visitable) //TODO: passableness problem -> town says it's passable (thus accessible) but we obviously can't disembark onto town gate
|
||||||
{
|
{
|
||||||
destination.blocked = true;
|
destination.blocked = true;
|
||||||
@@ -362,15 +362,15 @@ void LayerTransitionRule::process(
|
|||||||
case EPathfindingLayer::AIR:
|
case EPathfindingLayer::AIR:
|
||||||
if(pathfinderConfig->options.originalMovementRules)
|
if(pathfinderConfig->options.originalMovementRules)
|
||||||
{
|
{
|
||||||
if((source.node->accessible != CGPathNode::ACCESSIBLE &&
|
if((source.node->accessible != EPathAccessibility::ACCESSIBLE &&
|
||||||
source.node->accessible != CGPathNode::VISITABLE) &&
|
source.node->accessible != EPathAccessibility::VISITABLE) &&
|
||||||
(destination.node->accessible != CGPathNode::VISITABLE &&
|
(destination.node->accessible != EPathAccessibility::VISITABLE &&
|
||||||
destination.node->accessible != CGPathNode::ACCESSIBLE))
|
destination.node->accessible != EPathAccessibility::ACCESSIBLE))
|
||||||
{
|
{
|
||||||
destination.blocked = true;
|
destination.blocked = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(destination.node->accessible != CGPathNode::ACCESSIBLE)
|
else if(destination.node->accessible != EPathAccessibility::ACCESSIBLE)
|
||||||
{
|
{
|
||||||
/// Hero that fly can only land on accessible tiles
|
/// Hero that fly can only land on accessible tiles
|
||||||
if(destination.nodeObject)
|
if(destination.nodeObject)
|
||||||
@@ -380,7 +380,7 @@ void LayerTransitionRule::process(
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case EPathfindingLayer::WATER:
|
case EPathfindingLayer::WATER:
|
||||||
if(destination.node->accessible != CGPathNode::ACCESSIBLE && destination.node->accessible != CGPathNode::VISITABLE)
|
if(destination.node->accessible != EPathAccessibility::ACCESSIBLE && destination.node->accessible != EPathAccessibility::VISITABLE)
|
||||||
{
|
{
|
||||||
/// Hero that walking on water can transit to accessible and visitable tiles
|
/// Hero that walking on water can transit to accessible and visitable tiles
|
||||||
/// Though hero can't interact with blocking visit objects while standing on water
|
/// Though hero can't interact with blocking visit objects while standing on water
|
||||||
|
Reference in New Issue
Block a user