mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-26 22:57:00 +02:00
AI: extract pathfinding special actions and rules to separate files
This commit is contained in:
parent
0ccdd31586
commit
5454848938
@ -12,6 +12,13 @@ set(VCAI_SRCS
|
|||||||
Pathfinding/AIPathfinder.cpp
|
Pathfinding/AIPathfinder.cpp
|
||||||
Pathfinding/AINodeStorage.cpp
|
Pathfinding/AINodeStorage.cpp
|
||||||
Pathfinding/PathfindingManager.cpp
|
Pathfinding/PathfindingManager.cpp
|
||||||
|
Pathfinding/Actions/BattleAction.cpp
|
||||||
|
Pathfinding/Actions/BoatActions.cpp
|
||||||
|
Pathfinding/Actions/TownPortalAction.cpp
|
||||||
|
Pathfinding/Rules/AILayerTransitionRule.cpp
|
||||||
|
Pathfinding/Rules/AIMovementAfterDestinationRule.cpp
|
||||||
|
Pathfinding/Rules/AIMovementToDestinationRule.cpp
|
||||||
|
Pathfinding/Rules/AIPreviousNodeRule.cpp
|
||||||
AIUtility.cpp
|
AIUtility.cpp
|
||||||
AIhelper.cpp
|
AIhelper.cpp
|
||||||
ResourceManager.cpp
|
ResourceManager.cpp
|
||||||
@ -54,6 +61,14 @@ set(VCAI_HEADERS
|
|||||||
Pathfinding/AIPathfinder.h
|
Pathfinding/AIPathfinder.h
|
||||||
Pathfinding/AINodeStorage.h
|
Pathfinding/AINodeStorage.h
|
||||||
Pathfinding/PathfindingManager.h
|
Pathfinding/PathfindingManager.h
|
||||||
|
Pathfinding/Actions/ISpecialAction.h
|
||||||
|
Pathfinding/Actions/BattleAction.h
|
||||||
|
Pathfinding/Actions/BoatActions.h
|
||||||
|
Pathfinding/Actions/TownPortalAction.h
|
||||||
|
Pathfinding/Rules/AILayerTransitionRule.h
|
||||||
|
Pathfinding/Rules/AIMovementAfterDestinationRule.h
|
||||||
|
Pathfinding/Rules/AIMovementToDestinationRule.h
|
||||||
|
Pathfinding/Rules/AIPreviousNodeRule.h
|
||||||
AIUtility.h
|
AIUtility.h
|
||||||
AIhelper.h
|
AIhelper.h
|
||||||
ResourceManager.h
|
ResourceManager.h
|
||||||
|
@ -9,13 +9,14 @@
|
|||||||
*/
|
*/
|
||||||
#include "StdInc.h"
|
#include "StdInc.h"
|
||||||
#include "AINodeStorage.h"
|
#include "AINodeStorage.h"
|
||||||
|
#include "Actions/TownPortalAction.h"
|
||||||
#include "../Goals/Goals.h"
|
#include "../Goals/Goals.h"
|
||||||
#include "../../../CCallback.h"
|
#include "../../../CCallback.h"
|
||||||
#include "../../../lib/mapping/CMap.h"
|
#include "../../../lib/mapping/CMap.h"
|
||||||
#include "../../../lib/mapObjects/MapObjects.h"
|
#include "../../../lib/mapObjects/MapObjects.h"
|
||||||
|
|
||||||
#include "../../../lib/PathfinderUtil.h"
|
#include "../../../lib/PathfinderUtil.h"
|
||||||
#include "../../../lib/CPlayerState.h"
|
#include "../../../lib/CPlayerState.h"
|
||||||
|
|
||||||
extern boost::thread_specific_ptr<CCallback> cb;
|
extern boost::thread_specific_ptr<CCallback> cb;
|
||||||
|
|
||||||
|
|
||||||
@ -191,26 +192,6 @@ void AINodeStorage::setHero(HeroPtr heroPtr)
|
|||||||
hero = heroPtr.get();
|
hero = heroPtr.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
class TownPortalAction : public ISpecialAction
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
const CGTownInstance * target;
|
|
||||||
const HeroPtr hero;
|
|
||||||
|
|
||||||
public:
|
|
||||||
TownPortalAction(const CGTownInstance * target)
|
|
||||||
:target(target)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual Goals::TSubgoal whatToDo(HeroPtr hero) const override
|
|
||||||
{
|
|
||||||
const CGTownInstance * targetTown = target; // const pointer is not allowed in settown
|
|
||||||
|
|
||||||
return sptr(Goals::AdventureSpellCast(hero, SpellID::TOWN_PORTAL).settown(targetTown).settile(targetTown->visitablePos()));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
std::vector<CGPathNode *> AINodeStorage::calculateTeleportations(
|
std::vector<CGPathNode *> AINodeStorage::calculateTeleportations(
|
||||||
const PathNodeInfo & source,
|
const PathNodeInfo & source,
|
||||||
const PathfinderConfig * pathfinderConfig,
|
const PathfinderConfig * pathfinderConfig,
|
||||||
@ -299,7 +280,7 @@ void AINodeStorage::calculateTownPortalTeleportations(
|
|||||||
AIPathNode * node = nodeOptional.get();
|
AIPathNode * node = nodeOptional.get();
|
||||||
|
|
||||||
node->theNodeBefore = source.node;
|
node->theNodeBefore = source.node;
|
||||||
node->specialAction.reset(new TownPortalAction(targetTown));
|
node->specialAction.reset(new AIPathfinding::TownPortalAction(targetTown));
|
||||||
node->moveRemains = source.node->moveRemains;
|
node->moveRemains = source.node->moveRemains;
|
||||||
|
|
||||||
neighbours.push_back(node);
|
neighbours.push_back(node);
|
||||||
|
@ -14,24 +14,10 @@
|
|||||||
#include "../../../lib/mapObjects/CGHeroInstance.h"
|
#include "../../../lib/mapObjects/CGHeroInstance.h"
|
||||||
#include "../AIUtility.h"
|
#include "../AIUtility.h"
|
||||||
#include "../Goals/AbstractGoal.h"
|
#include "../Goals/AbstractGoal.h"
|
||||||
|
#include "Actions/ISpecialAction.h"
|
||||||
|
|
||||||
struct AIPathNode;
|
struct AIPathNode;
|
||||||
|
|
||||||
class ISpecialAction
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
virtual Goals::TSubgoal whatToDo(HeroPtr hero) const = 0;
|
|
||||||
|
|
||||||
virtual void applyOnDestination(
|
|
||||||
HeroPtr hero,
|
|
||||||
CDestinationNodeInfo & destination,
|
|
||||||
const PathNodeInfo & source,
|
|
||||||
AIPathNode * dstMode,
|
|
||||||
const AIPathNode * srcNode) const
|
|
||||||
{
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct AIPathNode : public CGPathNode
|
struct AIPathNode : public CGPathNode
|
||||||
{
|
{
|
||||||
uint32_t chainMask;
|
uint32_t chainMask;
|
||||||
|
@ -9,487 +9,13 @@
|
|||||||
*/
|
*/
|
||||||
#include "StdInc.h"
|
#include "StdInc.h"
|
||||||
#include "AIPathfinderConfig.h"
|
#include "AIPathfinderConfig.h"
|
||||||
#include "../Goals/Goals.h"
|
#include "Rules/AILayerTransitionRule.h"
|
||||||
#include "../../../CCallback.h"
|
#include "Rules/AIMovementAfterDestinationRule.h"
|
||||||
#include "../../../lib/mapping/CMap.h"
|
#include "Rules/AIMovementToDestinationRule.h"
|
||||||
#include "../../../lib/mapObjects/MapObjects.h"
|
#include "Rules/AIPreviousNodeRule.h"
|
||||||
|
|
||||||
namespace AIPathfinding
|
namespace AIPathfinding
|
||||||
{
|
{
|
||||||
class VirtualBoatAction : public ISpecialAction
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
uint64_t specialChain;
|
|
||||||
|
|
||||||
public:
|
|
||||||
VirtualBoatAction(uint64_t specialChain)
|
|
||||||
:specialChain(specialChain)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
uint64_t getSpecialChain() const
|
|
||||||
{
|
|
||||||
return specialChain;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class BuildBoatAction : public VirtualBoatAction
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
const IShipyard * shipyard;
|
|
||||||
|
|
||||||
public:
|
|
||||||
BuildBoatAction(const IShipyard * shipyard)
|
|
||||||
:VirtualBoatAction(AINodeStorage::RESOURCE_CHAIN), shipyard(shipyard)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual Goals::TSubgoal whatToDo(HeroPtr hero) const override
|
|
||||||
{
|
|
||||||
return sptr(Goals::BuildBoat(shipyard));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class SummonBoatAction : public VirtualBoatAction
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
SummonBoatAction()
|
|
||||||
:VirtualBoatAction(AINodeStorage::CAST_CHAIN)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual Goals::TSubgoal whatToDo(HeroPtr hero) const override
|
|
||||||
{
|
|
||||||
return sptr(Goals::AdventureSpellCast(hero, SpellID::SUMMON_BOAT));
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void applyOnDestination(
|
|
||||||
HeroPtr hero,
|
|
||||||
CDestinationNodeInfo & destination,
|
|
||||||
const PathNodeInfo & source,
|
|
||||||
AIPathNode * dstMode,
|
|
||||||
const AIPathNode * srcNode) const override
|
|
||||||
{
|
|
||||||
dstMode->manaCost = srcNode->manaCost + getManaCost(hero);
|
|
||||||
dstMode->theNodeBefore = source.node;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isAffordableBy(HeroPtr hero, const AIPathNode * source) const
|
|
||||||
{
|
|
||||||
#ifdef VCMI_TRACE_PATHFINDER
|
|
||||||
logAi->trace(
|
|
||||||
"Hero %s has %d mana and needed %d and already spent %d",
|
|
||||||
hero->name,
|
|
||||||
hero->mana,
|
|
||||||
getManaCost(hero),
|
|
||||||
source->manaCost);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return hero->mana >= source->manaCost + getManaCost(hero);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
uint32_t getManaCost(HeroPtr hero) const
|
|
||||||
{
|
|
||||||
SpellID summonBoat = SpellID::SUMMON_BOAT;
|
|
||||||
|
|
||||||
return hero->getSpellCost(summonBoat.toSpell());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class BattleAction : public ISpecialAction
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
const int3 target;
|
|
||||||
const HeroPtr hero;
|
|
||||||
|
|
||||||
public:
|
|
||||||
BattleAction(const int3 target)
|
|
||||||
:target(target)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual Goals::TSubgoal whatToDo(HeroPtr hero) const override
|
|
||||||
{
|
|
||||||
return sptr(Goals::VisitTile(target).sethero(hero));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class AILayerTransitionRule : public LayerTransitionRule
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
CPlayerSpecificInfoCallback * cb;
|
|
||||||
VCAI * ai;
|
|
||||||
std::map<int3, std::shared_ptr<const BuildBoatAction>> virtualBoats;
|
|
||||||
std::shared_ptr<AINodeStorage> nodeStorage;
|
|
||||||
std::shared_ptr<const SummonBoatAction> summonableVirtualBoat;
|
|
||||||
|
|
||||||
public:
|
|
||||||
AILayerTransitionRule(CPlayerSpecificInfoCallback * cb, VCAI * ai, std::shared_ptr<AINodeStorage> nodeStorage)
|
|
||||||
:cb(cb), ai(ai), nodeStorage(nodeStorage)
|
|
||||||
{
|
|
||||||
setup();
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void process(
|
|
||||||
const PathNodeInfo & source,
|
|
||||||
CDestinationNodeInfo & destination,
|
|
||||||
const PathfinderConfig * pathfinderConfig,
|
|
||||||
CPathfinderHelper * pathfinderHelper) const override
|
|
||||||
{
|
|
||||||
LayerTransitionRule::process(source, destination, pathfinderConfig, pathfinderHelper);
|
|
||||||
|
|
||||||
if(!destination.blocked)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(source.node->layer == EPathfindingLayer::LAND && destination.node->layer == EPathfindingLayer::SAIL)
|
|
||||||
{
|
|
||||||
std::shared_ptr<const VirtualBoatAction> virtualBoat = findVirtualBoat(destination, source);
|
|
||||||
|
|
||||||
if(virtualBoat && tryEmbarkVirtualBoat(destination, source, virtualBoat))
|
|
||||||
{
|
|
||||||
#ifdef VCMI_TRACE_PATHFINDER
|
|
||||||
logAi->trace("Embarking to virtual boat while moving %s -> %s!", source.coord.toString(), destination.coord.toString());
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
void setup()
|
|
||||||
{
|
|
||||||
std::vector<const IShipyard *> shipyards;
|
|
||||||
|
|
||||||
for(const CGTownInstance * t : cb->getTownsInfo())
|
|
||||||
{
|
|
||||||
if(t->hasBuilt(BuildingID::SHIPYARD))
|
|
||||||
shipyards.push_back(t);
|
|
||||||
}
|
|
||||||
|
|
||||||
for(const CGObjectInstance * obj : ai->visitableObjs)
|
|
||||||
{
|
|
||||||
if(obj->ID != Obj::TOWN) //towns were handled in the previous loop
|
|
||||||
{
|
|
||||||
if(const IShipyard * shipyard = IShipyard::castFrom(obj))
|
|
||||||
shipyards.push_back(shipyard);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for(const IShipyard * shipyard : shipyards)
|
|
||||||
{
|
|
||||||
if(shipyard->shipyardStatus() == IShipyard::GOOD)
|
|
||||||
{
|
|
||||||
int3 boatLocation = shipyard->bestLocation();
|
|
||||||
virtualBoats[boatLocation] = std::make_shared<BuildBoatAction>(shipyard);
|
|
||||||
logAi->debug("Virtual boat added at %s", boatLocation.toString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
auto hero = nodeStorage->getHero();
|
|
||||||
auto summonBoatSpell = SpellID(SpellID::SUMMON_BOAT).toSpell();
|
|
||||||
|
|
||||||
if(hero->canCastThisSpell(summonBoatSpell)
|
|
||||||
&& hero->getSpellSchoolLevel(summonBoatSpell) >= SecSkillLevel::ADVANCED)
|
|
||||||
{
|
|
||||||
// TODO: For lower school level we might need to check the existance of some boat
|
|
||||||
summonableVirtualBoat.reset(new SummonBoatAction());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
std::shared_ptr<const VirtualBoatAction> findVirtualBoat(
|
|
||||||
CDestinationNodeInfo &destination,
|
|
||||||
const PathNodeInfo &source) const
|
|
||||||
{
|
|
||||||
std::shared_ptr<const VirtualBoatAction> virtualBoat;
|
|
||||||
|
|
||||||
if(vstd::contains(virtualBoats, destination.coord))
|
|
||||||
{
|
|
||||||
virtualBoat = virtualBoats.at(destination.coord);
|
|
||||||
}
|
|
||||||
else if(
|
|
||||||
summonableVirtualBoat
|
|
||||||
&& summonableVirtualBoat->isAffordableBy(nodeStorage->getHero(), nodeStorage->getAINode(source.node)))
|
|
||||||
{
|
|
||||||
virtualBoat = summonableVirtualBoat;
|
|
||||||
}
|
|
||||||
|
|
||||||
return virtualBoat;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool tryEmbarkVirtualBoat(
|
|
||||||
CDestinationNodeInfo &destination,
|
|
||||||
const PathNodeInfo &source,
|
|
||||||
std::shared_ptr<const VirtualBoatAction> virtualBoat) const
|
|
||||||
{
|
|
||||||
bool result = false;
|
|
||||||
|
|
||||||
nodeStorage->updateAINode(destination.node, [&](AIPathNode * node)
|
|
||||||
{
|
|
||||||
auto boatNodeOptional = nodeStorage->getOrCreateNode(
|
|
||||||
node->coord,
|
|
||||||
node->layer,
|
|
||||||
node->chainMask | virtualBoat->getSpecialChain());
|
|
||||||
|
|
||||||
if(boatNodeOptional)
|
|
||||||
{
|
|
||||||
AIPathNode * boatNode = boatNodeOptional.get();
|
|
||||||
|
|
||||||
if(boatNode->action == CGPathNode::UNKNOWN)
|
|
||||||
{
|
|
||||||
boatNode->specialAction = virtualBoat;
|
|
||||||
destination.blocked = false;
|
|
||||||
destination.action = CGPathNode::ENodeAction::EMBARK;
|
|
||||||
destination.node = boatNode;
|
|
||||||
result = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
#ifdef VCMI_TRACE_PATHFINDER
|
|
||||||
logAi->trace(
|
|
||||||
"Special transition node already allocated. Blocked moving %s -> %s",
|
|
||||||
source.coord.toString(),
|
|
||||||
destination.coord.toString());
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
logAi->debug(
|
|
||||||
"Can not allocate special transition node while moving %s -> %s",
|
|
||||||
source.coord.toString(),
|
|
||||||
destination.coord.toString());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class AIMovementAfterDestinationRule : public MovementAfterDestinationRule
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
CPlayerSpecificInfoCallback * cb;
|
|
||||||
std::shared_ptr<AINodeStorage> nodeStorage;
|
|
||||||
|
|
||||||
public:
|
|
||||||
AIMovementAfterDestinationRule(CPlayerSpecificInfoCallback * cb, std::shared_ptr<AINodeStorage> nodeStorage)
|
|
||||||
:cb(cb), nodeStorage(nodeStorage)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void process(
|
|
||||||
const PathNodeInfo & source,
|
|
||||||
CDestinationNodeInfo & destination,
|
|
||||||
const PathfinderConfig * pathfinderConfig,
|
|
||||||
CPathfinderHelper * pathfinderHelper) const override
|
|
||||||
{
|
|
||||||
if(nodeStorage->hasBetterChain(source, destination))
|
|
||||||
{
|
|
||||||
destination.blocked = true;
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto blocker = getBlockingReason(source, destination, pathfinderConfig, pathfinderHelper);
|
|
||||||
|
|
||||||
if(blocker == BlockingReason::NONE)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if(blocker == BlockingReason::DESTINATION_BLOCKVIS && destination.nodeObject)
|
|
||||||
{
|
|
||||||
auto objID = destination.nodeObject->ID;
|
|
||||||
auto enemyHero = objID == Obj::HERO && destination.objectRelations == PlayerRelations::ENEMIES;
|
|
||||||
|
|
||||||
if(!enemyHero && !isObjectRemovable(destination.nodeObject))
|
|
||||||
{
|
|
||||||
destination.blocked = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(blocker == BlockingReason::DESTINATION_VISIT)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(blocker == BlockingReason::DESTINATION_GUARDED)
|
|
||||||
{
|
|
||||||
auto srcGuardians = cb->getGuardingCreatures(source.coord);
|
|
||||||
auto destGuardians = cb->getGuardingCreatures(destination.coord);
|
|
||||||
|
|
||||||
if(destGuardians.empty())
|
|
||||||
{
|
|
||||||
destination.blocked = true;
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
vstd::erase_if(destGuardians, [&](const CGObjectInstance * destGuard) -> bool
|
|
||||||
{
|
|
||||||
return vstd::contains(srcGuardians, destGuard);
|
|
||||||
});
|
|
||||||
|
|
||||||
auto guardsAlreadyBypassed = destGuardians.empty() && srcGuardians.size();
|
|
||||||
if(guardsAlreadyBypassed && nodeStorage->isBattleNode(source.node))
|
|
||||||
{
|
|
||||||
#ifdef VCMI_TRACE_PATHFINDER
|
|
||||||
logAi->trace(
|
|
||||||
"Bypass guard at destination while moving %s -> %s",
|
|
||||||
source.coord.toString(),
|
|
||||||
destination.coord.toString());
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const AIPathNode * destNode = nodeStorage->getAINode(destination.node);
|
|
||||||
auto battleNodeOptional = nodeStorage->getOrCreateNode(
|
|
||||||
destination.coord,
|
|
||||||
destination.node->layer,
|
|
||||||
destNode->chainMask | AINodeStorage::BATTLE_CHAIN);
|
|
||||||
|
|
||||||
if(!battleNodeOptional)
|
|
||||||
{
|
|
||||||
#ifdef VCMI_TRACE_PATHFINDER
|
|
||||||
logAi->trace(
|
|
||||||
"Can not allocate battle node while moving %s -> %s",
|
|
||||||
source.coord.toString(),
|
|
||||||
destination.coord.toString());
|
|
||||||
#endif
|
|
||||||
|
|
||||||
destination.blocked = true;
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
AIPathNode * battleNode = battleNodeOptional.get();
|
|
||||||
|
|
||||||
if(battleNode->locked)
|
|
||||||
{
|
|
||||||
#ifdef VCMI_TRACE_PATHFINDER
|
|
||||||
logAi->trace(
|
|
||||||
"Block bypass guard at destination while moving %s -> %s",
|
|
||||||
source.coord.toString(),
|
|
||||||
destination.coord.toString());
|
|
||||||
#endif
|
|
||||||
destination.blocked = true;
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto hero = nodeStorage->getHero();
|
|
||||||
auto danger = evaluateDanger(destination.coord, hero);
|
|
||||||
|
|
||||||
destination.node = battleNode;
|
|
||||||
nodeStorage->commit(destination, source);
|
|
||||||
|
|
||||||
if(battleNode->danger < danger)
|
|
||||||
{
|
|
||||||
battleNode->danger = danger;
|
|
||||||
}
|
|
||||||
|
|
||||||
battleNode->specialAction = std::make_shared<BattleAction>(destination.coord);
|
|
||||||
#ifdef VCMI_TRACE_PATHFINDER
|
|
||||||
logAi->trace(
|
|
||||||
"Begin bypass guard at destination with danger %s while moving %s -> %s",
|
|
||||||
std::to_string(danger),
|
|
||||||
source.coord.toString(),
|
|
||||||
destination.coord.toString());
|
|
||||||
#endif
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
destination.blocked = true;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class AIMovementToDestinationRule : public MovementToDestinationRule
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
std::shared_ptr<AINodeStorage> nodeStorage;
|
|
||||||
|
|
||||||
public:
|
|
||||||
AIMovementToDestinationRule(std::shared_ptr<AINodeStorage> nodeStorage)
|
|
||||||
: nodeStorage(nodeStorage)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void process(
|
|
||||||
const PathNodeInfo & source,
|
|
||||||
CDestinationNodeInfo & destination,
|
|
||||||
const PathfinderConfig * pathfinderConfig,
|
|
||||||
CPathfinderHelper * pathfinderHelper) const override
|
|
||||||
{
|
|
||||||
auto blocker = getBlockingReason(source, destination, pathfinderConfig, pathfinderHelper);
|
|
||||||
|
|
||||||
if(blocker == BlockingReason::NONE)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if(blocker == BlockingReason::DESTINATION_BLOCKED
|
|
||||||
&& destination.action == CGPathNode::EMBARK
|
|
||||||
&& nodeStorage->getAINode(destination.node)->specialAction)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(blocker == BlockingReason::SOURCE_GUARDED && nodeStorage->isBattleNode(source.node))
|
|
||||||
{
|
|
||||||
#ifdef VCMI_TRACE_PATHFINDER
|
|
||||||
logAi->trace(
|
|
||||||
"Bypass src guard while moving from %s to %s",
|
|
||||||
source.coord.toString(),
|
|
||||||
destination.coord.toString());
|
|
||||||
#endif
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
destination.blocked = true;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class AIPreviousNodeRule : public MovementToDestinationRule
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
std::shared_ptr<AINodeStorage> nodeStorage;
|
|
||||||
|
|
||||||
public:
|
|
||||||
AIPreviousNodeRule(std::shared_ptr<AINodeStorage> nodeStorage)
|
|
||||||
: nodeStorage(nodeStorage)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void process(
|
|
||||||
const PathNodeInfo & source,
|
|
||||||
CDestinationNodeInfo & destination,
|
|
||||||
const PathfinderConfig * pathfinderConfig,
|
|
||||||
CPathfinderHelper * pathfinderHelper) const override
|
|
||||||
{
|
|
||||||
if(source.node->action == CGPathNode::ENodeAction::BLOCKING_VISIT || source.node->action == CGPathNode::ENodeAction::VISIT)
|
|
||||||
{
|
|
||||||
// we can not directly bypass objects, we need to interact with them first
|
|
||||||
destination.node->theNodeBefore = source.node;
|
|
||||||
#ifdef VCMI_TRACE_PATHFINDER
|
|
||||||
logAi->trace(
|
|
||||||
"Link src node %s to destination node %s while bypassing visitable obj",
|
|
||||||
source.coord.toString(),
|
|
||||||
destination.coord.toString());
|
|
||||||
#endif
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto aiSourceNode = nodeStorage->getAINode(source.node);
|
|
||||||
|
|
||||||
if(aiSourceNode->specialAction)
|
|
||||||
{
|
|
||||||
// there is some action on source tile which should be performed before we can bypass it
|
|
||||||
destination.node->theNodeBefore = source.node;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
std::vector<std::shared_ptr<IPathfindingRule>> makeRuleset(
|
std::vector<std::shared_ptr<IPathfindingRule>> makeRuleset(
|
||||||
CPlayerSpecificInfoCallback * cb,
|
CPlayerSpecificInfoCallback * cb,
|
||||||
VCAI * ai,
|
VCAI * ai,
|
||||||
|
21
AI/VCAI/Pathfinding/Actions/BattleAction.cpp
Normal file
21
AI/VCAI/Pathfinding/Actions/BattleAction.cpp
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
/*
|
||||||
|
* BattleAction.cpp, part of VCMI engine
|
||||||
|
*
|
||||||
|
* Authors: listed in file AUTHORS in main folder
|
||||||
|
*
|
||||||
|
* License: GNU General Public License v2.0 or later
|
||||||
|
* Full text of license available in license.txt file, in main folder
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "StdInc.h"
|
||||||
|
#include "../../Goals/VisitTile.h"
|
||||||
|
#include "BattleAction.h"
|
||||||
|
|
||||||
|
namespace AIPathfinding
|
||||||
|
{
|
||||||
|
Goals::TSubgoal BattleAction::whatToDo(const HeroPtr & hero) const
|
||||||
|
{
|
||||||
|
return Goals::sptr(Goals::VisitTile(targetTile).sethero(hero));
|
||||||
|
}
|
||||||
|
}
|
30
AI/VCAI/Pathfinding/Actions/BattleAction.h
Normal file
30
AI/VCAI/Pathfinding/Actions/BattleAction.h
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
/*
|
||||||
|
* BattleAction.h, part of VCMI engine
|
||||||
|
*
|
||||||
|
* Authors: listed in file AUTHORS in main folder
|
||||||
|
*
|
||||||
|
* License: GNU General Public License v2.0 or later
|
||||||
|
* Full text of license available in license.txt file, in main folder
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "ISpecialAction.h"
|
||||||
|
|
||||||
|
namespace AIPathfinding
|
||||||
|
{
|
||||||
|
class BattleAction : public ISpecialAction
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
const int3 targetTile;
|
||||||
|
|
||||||
|
public:
|
||||||
|
BattleAction(const int3 targetTile)
|
||||||
|
:targetTile(targetTile)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual Goals::TSubgoal whatToDo(const HeroPtr & hero) const override;
|
||||||
|
};
|
||||||
|
}
|
61
AI/VCAI/Pathfinding/Actions/BoatActions.cpp
Normal file
61
AI/VCAI/Pathfinding/Actions/BoatActions.cpp
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
/*
|
||||||
|
* BoatActions.cpp, part of VCMI engine
|
||||||
|
*
|
||||||
|
* Authors: listed in file AUTHORS in main folder
|
||||||
|
*
|
||||||
|
* License: GNU General Public License v2.0 or later
|
||||||
|
* Full text of license available in license.txt file, in main folder
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "StdInc.h"
|
||||||
|
#include "../../Goals/AdventureSpellCast.h"
|
||||||
|
#include "../../Goals/BuildBoat.h"
|
||||||
|
#include "../../../../lib/mapping/CMap.h"
|
||||||
|
#include "../../../../lib/mapObjects/MapObjects.h"
|
||||||
|
#include "BoatActions.h"
|
||||||
|
|
||||||
|
namespace AIPathfinding
|
||||||
|
{
|
||||||
|
Goals::TSubgoal BuildBoatAction::whatToDo(const HeroPtr & hero) const
|
||||||
|
{
|
||||||
|
return Goals::sptr(Goals::BuildBoat(shipyard));
|
||||||
|
}
|
||||||
|
|
||||||
|
Goals::TSubgoal SummonBoatAction::whatToDo(const HeroPtr & hero) const
|
||||||
|
{
|
||||||
|
return Goals::sptr(Goals::AdventureSpellCast(hero, SpellID::SUMMON_BOAT));
|
||||||
|
}
|
||||||
|
|
||||||
|
void SummonBoatAction::applyOnDestination(
|
||||||
|
const HeroPtr & hero,
|
||||||
|
CDestinationNodeInfo & destination,
|
||||||
|
const PathNodeInfo & source,
|
||||||
|
AIPathNode * dstMode,
|
||||||
|
const AIPathNode * srcNode) const
|
||||||
|
{
|
||||||
|
dstMode->manaCost = srcNode->manaCost + getManaCost(hero);
|
||||||
|
dstMode->theNodeBefore = source.node;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SummonBoatAction::isAffordableBy(const HeroPtr & hero, const AIPathNode * source) const
|
||||||
|
{
|
||||||
|
#ifdef VCMI_TRACE_PATHFINDER
|
||||||
|
logAi->trace(
|
||||||
|
"Hero %s has %d mana and needed %d and already spent %d",
|
||||||
|
hero->name,
|
||||||
|
hero->mana,
|
||||||
|
getManaCost(hero),
|
||||||
|
source->manaCost);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return hero->mana >= source->manaCost + getManaCost(hero);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t SummonBoatAction::getManaCost(const HeroPtr & hero) const
|
||||||
|
{
|
||||||
|
SpellID summonBoat = SpellID::SUMMON_BOAT;
|
||||||
|
|
||||||
|
return hero->getSpellCost(summonBoat.toSpell());
|
||||||
|
}
|
||||||
|
}
|
72
AI/VCAI/Pathfinding/Actions/BoatActions.h
Normal file
72
AI/VCAI/Pathfinding/Actions/BoatActions.h
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
/*
|
||||||
|
* BoatActions.h, part of VCMI engine
|
||||||
|
*
|
||||||
|
* Authors: listed in file AUTHORS in main folder
|
||||||
|
*
|
||||||
|
* License: GNU General Public License v2.0 or later
|
||||||
|
* Full text of license available in license.txt file, in main folder
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "ISpecialAction.h"
|
||||||
|
#include "../../../lib/mapping/CMap.h"
|
||||||
|
#include "../../../lib/mapObjects/MapObjects.h"
|
||||||
|
|
||||||
|
namespace AIPathfinding
|
||||||
|
{
|
||||||
|
class VirtualBoatAction : public ISpecialAction
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
uint64_t specialChain;
|
||||||
|
|
||||||
|
public:
|
||||||
|
VirtualBoatAction(uint64_t specialChain)
|
||||||
|
:specialChain(specialChain)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t getSpecialChain() const
|
||||||
|
{
|
||||||
|
return specialChain;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class SummonBoatAction : public VirtualBoatAction
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SummonBoatAction()
|
||||||
|
:VirtualBoatAction(AINodeStorage::CAST_CHAIN)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual Goals::TSubgoal whatToDo(const HeroPtr & hero) const override;
|
||||||
|
|
||||||
|
virtual void applyOnDestination(
|
||||||
|
const HeroPtr & hero,
|
||||||
|
CDestinationNodeInfo & destination,
|
||||||
|
const PathNodeInfo & source,
|
||||||
|
AIPathNode * dstMode,
|
||||||
|
const AIPathNode * srcNode) const override;
|
||||||
|
|
||||||
|
bool isAffordableBy(const HeroPtr & hero, const AIPathNode * source) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
uint32_t getManaCost(const HeroPtr & hero) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
class BuildBoatAction : public VirtualBoatAction
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
const IShipyard * shipyard;
|
||||||
|
|
||||||
|
public:
|
||||||
|
BuildBoatAction(const IShipyard * shipyard)
|
||||||
|
:VirtualBoatAction(AINodeStorage::RESOURCE_CHAIN), shipyard(shipyard)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual Goals::TSubgoal whatToDo(const HeroPtr & hero) const override;
|
||||||
|
};
|
||||||
|
}
|
31
AI/VCAI/Pathfinding/Actions/ISpecialAction.h
Normal file
31
AI/VCAI/Pathfinding/Actions/ISpecialAction.h
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
/*
|
||||||
|
* ISpecialAction.h, part of VCMI engine
|
||||||
|
*
|
||||||
|
* Authors: listed in file AUTHORS in main folder
|
||||||
|
*
|
||||||
|
* License: GNU General Public License v2.0 or later
|
||||||
|
* Full text of license available in license.txt file, in main folder
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "../../AIUtility.h"
|
||||||
|
#include "../../Goals/AbstractGoal.h"
|
||||||
|
|
||||||
|
class AIPathNode;
|
||||||
|
|
||||||
|
class ISpecialAction
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual Goals::TSubgoal whatToDo(const HeroPtr & hero) const = 0;
|
||||||
|
|
||||||
|
virtual void applyOnDestination(
|
||||||
|
const HeroPtr & hero,
|
||||||
|
CDestinationNodeInfo & destination,
|
||||||
|
const PathNodeInfo & source,
|
||||||
|
AIPathNode * dstMode,
|
||||||
|
const AIPathNode * srcNode) const
|
||||||
|
{
|
||||||
|
}
|
||||||
|
};
|
24
AI/VCAI/Pathfinding/Actions/TownPortalAction.cpp
Normal file
24
AI/VCAI/Pathfinding/Actions/TownPortalAction.cpp
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
/*
|
||||||
|
* TownPortalAction.cpp, part of VCMI engine
|
||||||
|
*
|
||||||
|
* Authors: listed in file AUTHORS in main folder
|
||||||
|
*
|
||||||
|
* License: GNU General Public License v2.0 or later
|
||||||
|
* Full text of license available in license.txt file, in main folder
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "StdInc.h"
|
||||||
|
#include "../../Goals/AdventureSpellCast.h"
|
||||||
|
#include "../../../../lib/mapping/CMap.h"
|
||||||
|
#include "../../../../lib/mapObjects/MapObjects.h"
|
||||||
|
#include "TownPortalAction.h"
|
||||||
|
|
||||||
|
using namespace AIPathfinding;
|
||||||
|
|
||||||
|
Goals::TSubgoal TownPortalAction::whatToDo(const HeroPtr & hero) const
|
||||||
|
{
|
||||||
|
const CGTownInstance * targetTown = target; // const pointer is not allowed in settown
|
||||||
|
|
||||||
|
return Goals::sptr(Goals::AdventureSpellCast(hero, SpellID::TOWN_PORTAL).settown(targetTown).settile(targetTown->visitablePos()));
|
||||||
|
}
|
33
AI/VCAI/Pathfinding/Actions/TownPortalAction.h
Normal file
33
AI/VCAI/Pathfinding/Actions/TownPortalAction.h
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
/*
|
||||||
|
* TownPortalAction.h, part of VCMI engine
|
||||||
|
*
|
||||||
|
* Authors: listed in file AUTHORS in main folder
|
||||||
|
*
|
||||||
|
* License: GNU General Public License v2.0 or later
|
||||||
|
* Full text of license available in license.txt file, in main folder
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "ISpecialAction.h"
|
||||||
|
#include "../../../lib/mapping/CMap.h"
|
||||||
|
#include "../../../lib/mapObjects/MapObjects.h"
|
||||||
|
#include "../../Goals/AdventureSpellCast.h"
|
||||||
|
|
||||||
|
namespace AIPathfinding
|
||||||
|
{
|
||||||
|
class TownPortalAction : public ISpecialAction
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
const CGTownInstance * target;
|
||||||
|
|
||||||
|
public:
|
||||||
|
TownPortalAction(const CGTownInstance * target)
|
||||||
|
:target(target)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual Goals::TSubgoal whatToDo(const HeroPtr & hero) const override;
|
||||||
|
};
|
||||||
|
}
|
154
AI/VCAI/Pathfinding/Rules/AILayerTransitionRule.cpp
Normal file
154
AI/VCAI/Pathfinding/Rules/AILayerTransitionRule.cpp
Normal file
@ -0,0 +1,154 @@
|
|||||||
|
/*
|
||||||
|
* AILayerTransitionRule.cpp, part of VCMI engine
|
||||||
|
*
|
||||||
|
* Authors: listed in file AUTHORS in main folder
|
||||||
|
*
|
||||||
|
* License: GNU General Public License v2.0 or later
|
||||||
|
* Full text of license available in license.txt file, in main folder
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#include "StdInc.h"
|
||||||
|
#include "AILayerTransitionRule.h"
|
||||||
|
|
||||||
|
namespace AIPathfinding
|
||||||
|
{
|
||||||
|
AILayerTransitionRule::AILayerTransitionRule(CPlayerSpecificInfoCallback * cb, VCAI * ai, std::shared_ptr<AINodeStorage> nodeStorage)
|
||||||
|
:cb(cb), ai(ai), nodeStorage(nodeStorage)
|
||||||
|
{
|
||||||
|
setup();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AILayerTransitionRule::process(
|
||||||
|
const PathNodeInfo & source,
|
||||||
|
CDestinationNodeInfo & destination,
|
||||||
|
const PathfinderConfig * pathfinderConfig,
|
||||||
|
CPathfinderHelper * pathfinderHelper) const
|
||||||
|
{
|
||||||
|
LayerTransitionRule::process(source, destination, pathfinderConfig, pathfinderHelper);
|
||||||
|
|
||||||
|
if(!destination.blocked)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(source.node->layer == EPathfindingLayer::LAND && destination.node->layer == EPathfindingLayer::SAIL)
|
||||||
|
{
|
||||||
|
std::shared_ptr<const VirtualBoatAction> virtualBoat = findVirtualBoat(destination, source);
|
||||||
|
|
||||||
|
if(virtualBoat && tryEmbarkVirtualBoat(destination, source, virtualBoat))
|
||||||
|
{
|
||||||
|
#ifdef VCMI_TRACE_PATHFINDER
|
||||||
|
logAi->trace("Embarking to virtual boat while moving %s -> %s!", source.coord.toString(), destination.coord.toString());
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AILayerTransitionRule::setup()
|
||||||
|
{
|
||||||
|
std::vector<const IShipyard *> shipyards;
|
||||||
|
|
||||||
|
for(const CGTownInstance * t : cb->getTownsInfo())
|
||||||
|
{
|
||||||
|
if(t->hasBuilt(BuildingID::SHIPYARD))
|
||||||
|
shipyards.push_back(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
for(const CGObjectInstance * obj : ai->visitableObjs)
|
||||||
|
{
|
||||||
|
if(obj->ID != Obj::TOWN) //towns were handled in the previous loop
|
||||||
|
{
|
||||||
|
if(const IShipyard * shipyard = IShipyard::castFrom(obj))
|
||||||
|
shipyards.push_back(shipyard);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for(const IShipyard * shipyard : shipyards)
|
||||||
|
{
|
||||||
|
if(shipyard->shipyardStatus() == IShipyard::GOOD)
|
||||||
|
{
|
||||||
|
int3 boatLocation = shipyard->bestLocation();
|
||||||
|
virtualBoats[boatLocation] = std::make_shared<BuildBoatAction>(shipyard);
|
||||||
|
logAi->debug("Virtual boat added at %s", boatLocation.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto hero = nodeStorage->getHero();
|
||||||
|
auto summonBoatSpell = SpellID(SpellID::SUMMON_BOAT).toSpell();
|
||||||
|
|
||||||
|
if(hero->canCastThisSpell(summonBoatSpell)
|
||||||
|
&& hero->getSpellSchoolLevel(summonBoatSpell) >= SecSkillLevel::ADVANCED)
|
||||||
|
{
|
||||||
|
// TODO: For lower school level we might need to check the existance of some boat
|
||||||
|
summonableVirtualBoat.reset(new SummonBoatAction());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<const VirtualBoatAction> AILayerTransitionRule::findVirtualBoat(
|
||||||
|
CDestinationNodeInfo & destination,
|
||||||
|
const PathNodeInfo & source) const
|
||||||
|
{
|
||||||
|
std::shared_ptr<const VirtualBoatAction> virtualBoat;
|
||||||
|
|
||||||
|
if(vstd::contains(virtualBoats, destination.coord))
|
||||||
|
{
|
||||||
|
virtualBoat = virtualBoats.at(destination.coord);
|
||||||
|
}
|
||||||
|
else if(
|
||||||
|
summonableVirtualBoat
|
||||||
|
&& summonableVirtualBoat->isAffordableBy(nodeStorage->getHero(), nodeStorage->getAINode(source.node)))
|
||||||
|
{
|
||||||
|
virtualBoat = summonableVirtualBoat;
|
||||||
|
}
|
||||||
|
|
||||||
|
return virtualBoat;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AILayerTransitionRule::tryEmbarkVirtualBoat(
|
||||||
|
CDestinationNodeInfo & destination,
|
||||||
|
const PathNodeInfo & source,
|
||||||
|
std::shared_ptr<const VirtualBoatAction> virtualBoat) const
|
||||||
|
{
|
||||||
|
bool result = false;
|
||||||
|
|
||||||
|
nodeStorage->updateAINode(destination.node, [&](AIPathNode * node)
|
||||||
|
{
|
||||||
|
auto boatNodeOptional = nodeStorage->getOrCreateNode(
|
||||||
|
node->coord,
|
||||||
|
node->layer,
|
||||||
|
node->chainMask | virtualBoat->getSpecialChain());
|
||||||
|
|
||||||
|
if(boatNodeOptional)
|
||||||
|
{
|
||||||
|
AIPathNode * boatNode = boatNodeOptional.get();
|
||||||
|
|
||||||
|
if(boatNode->action == CGPathNode::UNKNOWN)
|
||||||
|
{
|
||||||
|
boatNode->specialAction = virtualBoat;
|
||||||
|
destination.blocked = false;
|
||||||
|
destination.action = CGPathNode::ENodeAction::EMBARK;
|
||||||
|
destination.node = boatNode;
|
||||||
|
result = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
#ifdef VCMI_TRACE_PATHFINDER
|
||||||
|
logAi->trace(
|
||||||
|
"Special transition node already allocated. Blocked moving %s -> %s",
|
||||||
|
source.coord.toString(),
|
||||||
|
destination.coord.toString());
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
logAi->debug(
|
||||||
|
"Can not allocate special transition node while moving %s -> %s",
|
||||||
|
source.coord.toString(),
|
||||||
|
destination.coord.toString());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
52
AI/VCAI/Pathfinding/Rules/AILayerTransitionRule.h
Normal file
52
AI/VCAI/Pathfinding/Rules/AILayerTransitionRule.h
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
/*
|
||||||
|
* AILayerTransitionRule.h, part of VCMI engine
|
||||||
|
*
|
||||||
|
* Authors: listed in file AUTHORS in main folder
|
||||||
|
*
|
||||||
|
* License: GNU General Public License v2.0 or later
|
||||||
|
* Full text of license available in license.txt file, in main folder
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "../AINodeStorage.h"
|
||||||
|
#include "../../VCAI.h"
|
||||||
|
#include "../Actions/BoatActions.h"
|
||||||
|
#include "../../../../CCallback.h"
|
||||||
|
#include "../../../../lib/mapping/CMap.h"
|
||||||
|
#include "../../../../lib/mapObjects/MapObjects.h"
|
||||||
|
|
||||||
|
namespace AIPathfinding
|
||||||
|
{
|
||||||
|
class AILayerTransitionRule : public LayerTransitionRule
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
CPlayerSpecificInfoCallback * cb;
|
||||||
|
VCAI * ai;
|
||||||
|
std::map<int3, std::shared_ptr<const BuildBoatAction>> virtualBoats;
|
||||||
|
std::shared_ptr<AINodeStorage> nodeStorage;
|
||||||
|
std::shared_ptr<const SummonBoatAction> summonableVirtualBoat;
|
||||||
|
|
||||||
|
public:
|
||||||
|
AILayerTransitionRule(CPlayerSpecificInfoCallback * cb, VCAI * ai, std::shared_ptr<AINodeStorage> nodeStorage);
|
||||||
|
|
||||||
|
virtual void process(
|
||||||
|
const PathNodeInfo & source,
|
||||||
|
CDestinationNodeInfo & destination,
|
||||||
|
const PathfinderConfig * pathfinderConfig,
|
||||||
|
CPathfinderHelper * pathfinderHelper) const override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void setup();
|
||||||
|
|
||||||
|
std::shared_ptr<const VirtualBoatAction> findVirtualBoat(
|
||||||
|
CDestinationNodeInfo & destination,
|
||||||
|
const PathNodeInfo & source) const;
|
||||||
|
|
||||||
|
bool tryEmbarkVirtualBoat(
|
||||||
|
CDestinationNodeInfo & destination,
|
||||||
|
const PathNodeInfo & source,
|
||||||
|
std::shared_ptr<const VirtualBoatAction> virtualBoat) const;
|
||||||
|
};
|
||||||
|
}
|
148
AI/VCAI/Pathfinding/Rules/AIMovementAfterDestinationRule.cpp
Normal file
148
AI/VCAI/Pathfinding/Rules/AIMovementAfterDestinationRule.cpp
Normal file
@ -0,0 +1,148 @@
|
|||||||
|
/*
|
||||||
|
* AIMovementAfterDestinationRule.cpp, part of VCMI engine
|
||||||
|
*
|
||||||
|
* Authors: listed in file AUTHORS in main folder
|
||||||
|
*
|
||||||
|
* License: GNU General Public License v2.0 or later
|
||||||
|
* Full text of license available in license.txt file, in main folder
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#include "StdInc.h"
|
||||||
|
#include "AIMovementAfterDestinationRule.h"
|
||||||
|
#include "../Actions/BattleAction.h"
|
||||||
|
|
||||||
|
namespace AIPathfinding
|
||||||
|
{
|
||||||
|
AIMovementAfterDestinationRule::AIMovementAfterDestinationRule(
|
||||||
|
CPlayerSpecificInfoCallback * cb,
|
||||||
|
std::shared_ptr<AINodeStorage> nodeStorage)
|
||||||
|
:cb(cb), nodeStorage(nodeStorage)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void AIMovementAfterDestinationRule::process(
|
||||||
|
const PathNodeInfo & source,
|
||||||
|
CDestinationNodeInfo & destination,
|
||||||
|
const PathfinderConfig * pathfinderConfig,
|
||||||
|
CPathfinderHelper * pathfinderHelper) const
|
||||||
|
{
|
||||||
|
if(nodeStorage->hasBetterChain(source, destination))
|
||||||
|
{
|
||||||
|
destination.blocked = true;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto blocker = getBlockingReason(source, destination, pathfinderConfig, pathfinderHelper);
|
||||||
|
|
||||||
|
if(blocker == BlockingReason::NONE)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if(blocker == BlockingReason::DESTINATION_BLOCKVIS && destination.nodeObject)
|
||||||
|
{
|
||||||
|
auto objID = destination.nodeObject->ID;
|
||||||
|
auto enemyHero = objID == Obj::HERO && destination.objectRelations == PlayerRelations::ENEMIES;
|
||||||
|
|
||||||
|
if(!enemyHero && !isObjectRemovable(destination.nodeObject))
|
||||||
|
{
|
||||||
|
destination.blocked = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(blocker == BlockingReason::DESTINATION_VISIT)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(blocker == BlockingReason::DESTINATION_GUARDED)
|
||||||
|
{
|
||||||
|
auto srcGuardians = cb->getGuardingCreatures(source.coord);
|
||||||
|
auto destGuardians = cb->getGuardingCreatures(destination.coord);
|
||||||
|
|
||||||
|
if(destGuardians.empty())
|
||||||
|
{
|
||||||
|
destination.blocked = true;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
vstd::erase_if(destGuardians, [&](const CGObjectInstance * destGuard) -> bool
|
||||||
|
{
|
||||||
|
return vstd::contains(srcGuardians, destGuard);
|
||||||
|
});
|
||||||
|
|
||||||
|
auto guardsAlreadyBypassed = destGuardians.empty() && srcGuardians.size();
|
||||||
|
if(guardsAlreadyBypassed && nodeStorage->isBattleNode(source.node))
|
||||||
|
{
|
||||||
|
#ifdef VCMI_TRACE_PATHFINDER
|
||||||
|
logAi->trace(
|
||||||
|
"Bypass guard at destination while moving %s -> %s",
|
||||||
|
source.coord.toString(),
|
||||||
|
destination.coord.toString());
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const AIPathNode * destNode = nodeStorage->getAINode(destination.node);
|
||||||
|
auto battleNodeOptional = nodeStorage->getOrCreateNode(
|
||||||
|
destination.coord,
|
||||||
|
destination.node->layer,
|
||||||
|
destNode->chainMask | AINodeStorage::BATTLE_CHAIN);
|
||||||
|
|
||||||
|
if(!battleNodeOptional)
|
||||||
|
{
|
||||||
|
#ifdef VCMI_TRACE_PATHFINDER
|
||||||
|
logAi->trace(
|
||||||
|
"Can not allocate battle node while moving %s -> %s",
|
||||||
|
source.coord.toString(),
|
||||||
|
destination.coord.toString());
|
||||||
|
#endif
|
||||||
|
|
||||||
|
destination.blocked = true;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
AIPathNode * battleNode = battleNodeOptional.get();
|
||||||
|
|
||||||
|
if(battleNode->locked)
|
||||||
|
{
|
||||||
|
#ifdef VCMI_TRACE_PATHFINDER
|
||||||
|
logAi->trace(
|
||||||
|
"Block bypass guard at destination while moving %s -> %s",
|
||||||
|
source.coord.toString(),
|
||||||
|
destination.coord.toString());
|
||||||
|
#endif
|
||||||
|
destination.blocked = true;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto hero = nodeStorage->getHero();
|
||||||
|
auto danger = evaluateDanger(destination.coord, hero);
|
||||||
|
|
||||||
|
destination.node = battleNode;
|
||||||
|
nodeStorage->commit(destination, source);
|
||||||
|
|
||||||
|
if(battleNode->danger < danger)
|
||||||
|
{
|
||||||
|
battleNode->danger = danger;
|
||||||
|
}
|
||||||
|
|
||||||
|
battleNode->specialAction = std::make_shared<BattleAction>(destination.coord);
|
||||||
|
#ifdef VCMI_TRACE_PATHFINDER
|
||||||
|
logAi->trace(
|
||||||
|
"Begin bypass guard at destination with danger %s while moving %s -> %s",
|
||||||
|
std::to_string(danger),
|
||||||
|
source.coord.toString(),
|
||||||
|
destination.coord.toString());
|
||||||
|
#endif
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
destination.blocked = true;
|
||||||
|
}
|
||||||
|
}
|
36
AI/VCAI/Pathfinding/Rules/AIMovementAfterDestinationRule.h
Normal file
36
AI/VCAI/Pathfinding/Rules/AIMovementAfterDestinationRule.h
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
/*
|
||||||
|
* AIMovementAfterDestinationRule.h, part of VCMI engine
|
||||||
|
*
|
||||||
|
* Authors: listed in file AUTHORS in main folder
|
||||||
|
*
|
||||||
|
* License: GNU General Public License v2.0 or later
|
||||||
|
* Full text of license available in license.txt file, in main folder
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "../AINodeStorage.h"
|
||||||
|
#include "../../VCAI.h"
|
||||||
|
#include "../../../../CCallback.h"
|
||||||
|
#include "../../../../lib/mapping/CMap.h"
|
||||||
|
#include "../../../../lib/mapObjects/MapObjects.h"
|
||||||
|
|
||||||
|
namespace AIPathfinding
|
||||||
|
{
|
||||||
|
class AIMovementAfterDestinationRule : public MovementAfterDestinationRule
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
CPlayerSpecificInfoCallback * cb;
|
||||||
|
std::shared_ptr<AINodeStorage> nodeStorage;
|
||||||
|
|
||||||
|
public:
|
||||||
|
AIMovementAfterDestinationRule(CPlayerSpecificInfoCallback * cb, std::shared_ptr<AINodeStorage> nodeStorage);
|
||||||
|
|
||||||
|
virtual void process(
|
||||||
|
const PathNodeInfo & source,
|
||||||
|
CDestinationNodeInfo & destination,
|
||||||
|
const PathfinderConfig * pathfinderConfig,
|
||||||
|
CPathfinderHelper * pathfinderHelper) const override;
|
||||||
|
};
|
||||||
|
}
|
51
AI/VCAI/Pathfinding/Rules/AIMovementToDestinationRule.cpp
Normal file
51
AI/VCAI/Pathfinding/Rules/AIMovementToDestinationRule.cpp
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
/*
|
||||||
|
* AIMovementToDestinationRule.cpp, part of VCMI engine
|
||||||
|
*
|
||||||
|
* Authors: listed in file AUTHORS in main folder
|
||||||
|
*
|
||||||
|
* License: GNU General Public License v2.0 or later
|
||||||
|
* Full text of license available in license.txt file, in main folder
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#include "StdInc.h"
|
||||||
|
#include "AIMovementToDestinationRule.h"
|
||||||
|
|
||||||
|
namespace AIPathfinding
|
||||||
|
{
|
||||||
|
AIMovementToDestinationRule::AIMovementToDestinationRule(std::shared_ptr<AINodeStorage> nodeStorage)
|
||||||
|
: nodeStorage(nodeStorage)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void AIMovementToDestinationRule::process(
|
||||||
|
const PathNodeInfo & source,
|
||||||
|
CDestinationNodeInfo & destination,
|
||||||
|
const PathfinderConfig * pathfinderConfig,
|
||||||
|
CPathfinderHelper * pathfinderHelper) const
|
||||||
|
{
|
||||||
|
auto blocker = getBlockingReason(source, destination, pathfinderConfig, pathfinderHelper);
|
||||||
|
|
||||||
|
if(blocker == BlockingReason::NONE)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if(blocker == BlockingReason::DESTINATION_BLOCKED
|
||||||
|
&& destination.action == CGPathNode::EMBARK
|
||||||
|
&& nodeStorage->getAINode(destination.node)->specialAction)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(blocker == BlockingReason::SOURCE_GUARDED && nodeStorage->isBattleNode(source.node))
|
||||||
|
{
|
||||||
|
#ifdef VCMI_TRACE_PATHFINDER
|
||||||
|
logAi->trace(
|
||||||
|
"Bypass src guard while moving from %s to %s",
|
||||||
|
source.coord.toString(),
|
||||||
|
destination.coord.toString());
|
||||||
|
#endif
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
destination.blocked = true;
|
||||||
|
}
|
||||||
|
}
|
35
AI/VCAI/Pathfinding/Rules/AIMovementToDestinationRule.h
Normal file
35
AI/VCAI/Pathfinding/Rules/AIMovementToDestinationRule.h
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
/*
|
||||||
|
* AIMovementToDestinationRule.h, part of VCMI engine
|
||||||
|
*
|
||||||
|
* Authors: listed in file AUTHORS in main folder
|
||||||
|
*
|
||||||
|
* License: GNU General Public License v2.0 or later
|
||||||
|
* Full text of license available in license.txt file, in main folder
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "../AINodeStorage.h"
|
||||||
|
#include "../../VCAI.h"
|
||||||
|
#include "../../../../CCallback.h"
|
||||||
|
#include "../../../../lib/mapping/CMap.h"
|
||||||
|
#include "../../../../lib/mapObjects/MapObjects.h"
|
||||||
|
|
||||||
|
namespace AIPathfinding
|
||||||
|
{
|
||||||
|
class AIMovementToDestinationRule : public MovementToDestinationRule
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
std::shared_ptr<AINodeStorage> nodeStorage;
|
||||||
|
|
||||||
|
public:
|
||||||
|
AIMovementToDestinationRule(std::shared_ptr<AINodeStorage> nodeStorage);
|
||||||
|
|
||||||
|
virtual void process(
|
||||||
|
const PathNodeInfo & source,
|
||||||
|
CDestinationNodeInfo & destination,
|
||||||
|
const PathfinderConfig * pathfinderConfig,
|
||||||
|
CPathfinderHelper * pathfinderHelper) const override;
|
||||||
|
};
|
||||||
|
}
|
47
AI/VCAI/Pathfinding/Rules/AIPreviousNodeRule.cpp
Normal file
47
AI/VCAI/Pathfinding/Rules/AIPreviousNodeRule.cpp
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
/*
|
||||||
|
* AIPreviousNodeRule.cpp, part of VCMI engine
|
||||||
|
*
|
||||||
|
* Authors: listed in file AUTHORS in main folder
|
||||||
|
*
|
||||||
|
* License: GNU General Public License v2.0 or later
|
||||||
|
* Full text of license available in license.txt file, in main folder
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#include "StdInc.h"
|
||||||
|
#include "AIPreviousNodeRule.h"
|
||||||
|
|
||||||
|
namespace AIPathfinding
|
||||||
|
{
|
||||||
|
AIPreviousNodeRule::AIPreviousNodeRule(std::shared_ptr<AINodeStorage> nodeStorage)
|
||||||
|
: nodeStorage(nodeStorage)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void AIPreviousNodeRule::process(
|
||||||
|
const PathNodeInfo & source,
|
||||||
|
CDestinationNodeInfo & destination,
|
||||||
|
const PathfinderConfig * pathfinderConfig,
|
||||||
|
CPathfinderHelper * pathfinderHelper) const
|
||||||
|
{
|
||||||
|
if(source.node->action == CGPathNode::ENodeAction::BLOCKING_VISIT || source.node->action == CGPathNode::ENodeAction::VISIT)
|
||||||
|
{
|
||||||
|
// we can not directly bypass objects, we need to interact with them first
|
||||||
|
destination.node->theNodeBefore = source.node;
|
||||||
|
#ifdef VCMI_TRACE_PATHFINDER
|
||||||
|
logAi->trace(
|
||||||
|
"Link src node %s to destination node %s while bypassing visitable obj",
|
||||||
|
source.coord.toString(),
|
||||||
|
destination.coord.toString());
|
||||||
|
#endif
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto aiSourceNode = nodeStorage->getAINode(source.node);
|
||||||
|
|
||||||
|
if(aiSourceNode->specialAction)
|
||||||
|
{
|
||||||
|
// there is some action on source tile which should be performed before we can bypass it
|
||||||
|
destination.node->theNodeBefore = source.node;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
35
AI/VCAI/Pathfinding/Rules/AIPreviousNodeRule.h
Normal file
35
AI/VCAI/Pathfinding/Rules/AIPreviousNodeRule.h
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
/*
|
||||||
|
* AIPreviousNodeRule.h, part of VCMI engine
|
||||||
|
*
|
||||||
|
* Authors: listed in file AUTHORS in main folder
|
||||||
|
*
|
||||||
|
* License: GNU General Public License v2.0 or later
|
||||||
|
* Full text of license available in license.txt file, in main folder
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "../AINodeStorage.h"
|
||||||
|
#include "../../VCAI.h"
|
||||||
|
#include "../../../../CCallback.h"
|
||||||
|
#include "../../../../lib/mapping/CMap.h"
|
||||||
|
#include "../../../../lib/mapObjects/MapObjects.h"
|
||||||
|
|
||||||
|
namespace AIPathfinding
|
||||||
|
{
|
||||||
|
class AIPreviousNodeRule : public MovementToDestinationRule
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
std::shared_ptr<AINodeStorage> nodeStorage;
|
||||||
|
|
||||||
|
public:
|
||||||
|
AIPreviousNodeRule(std::shared_ptr<AINodeStorage> nodeStorage);
|
||||||
|
|
||||||
|
virtual void process(
|
||||||
|
const PathNodeInfo & source,
|
||||||
|
CDestinationNodeInfo & destination,
|
||||||
|
const PathfinderConfig * pathfinderConfig,
|
||||||
|
CPathfinderHelper * pathfinderHelper) const override;
|
||||||
|
};
|
||||||
|
}
|
@ -168,10 +168,20 @@
|
|||||||
<ClCompile Include="Goals\Win.cpp" />
|
<ClCompile Include="Goals\Win.cpp" />
|
||||||
<ClCompile Include="main.cpp" />
|
<ClCompile Include="main.cpp" />
|
||||||
<ClCompile Include="MapObjectsEvaluator.cpp" />
|
<ClCompile Include="MapObjectsEvaluator.cpp" />
|
||||||
|
<ClInclude Include="Pathfinding\Actions\BattleAction.h" />
|
||||||
|
<ClInclude Include="Pathfinding\Actions\TownPortalAction.h" />
|
||||||
|
<ClCompile Include="Pathfinding\Actions\BattleAction.cpp" />
|
||||||
|
<ClCompile Include="Pathfinding\Actions\TownPortalAction.cpp" />
|
||||||
|
<ClInclude Include="Pathfinding\Actions\BoatActions.h" />
|
||||||
|
<ClCompile Include="Pathfinding\Actions\BoatActions.cpp" />
|
||||||
<ClCompile Include="Pathfinding\AINodeStorage.cpp" />
|
<ClCompile Include="Pathfinding\AINodeStorage.cpp" />
|
||||||
<ClCompile Include="Pathfinding\AIPathfinder.cpp" />
|
<ClCompile Include="Pathfinding\AIPathfinder.cpp" />
|
||||||
<ClCompile Include="Pathfinding\AIPathfinderConfig.cpp" />
|
<ClCompile Include="Pathfinding\AIPathfinderConfig.cpp" />
|
||||||
<ClCompile Include="Pathfinding\PathfindingManager.cpp" />
|
<ClCompile Include="Pathfinding\PathfindingManager.cpp" />
|
||||||
|
<ClCompile Include="Pathfinding\Rules\AILayerTransitionRule.cpp" />
|
||||||
|
<ClCompile Include="Pathfinding\Rules\AIMovementAfterDestinationRule.cpp" />
|
||||||
|
<ClCompile Include="Pathfinding\Rules\AIMovementToDestinationRule.cpp" />
|
||||||
|
<ClCompile Include="Pathfinding\Rules\AIPreviousNodeRule.cpp" />
|
||||||
<ClCompile Include="ResourceManager.cpp" />
|
<ClCompile Include="ResourceManager.cpp" />
|
||||||
<ClCompile Include="SectorMap.cpp" />
|
<ClCompile Include="SectorMap.cpp" />
|
||||||
<ClCompile Include="StdInc.cpp">
|
<ClCompile Include="StdInc.cpp">
|
||||||
@ -214,10 +224,15 @@
|
|||||||
<ClInclude Include="Goals\VisitTile.h" />
|
<ClInclude Include="Goals\VisitTile.h" />
|
||||||
<ClInclude Include="Goals\Win.h" />
|
<ClInclude Include="Goals\Win.h" />
|
||||||
<ClInclude Include="MapObjectsEvaluator.h" />
|
<ClInclude Include="MapObjectsEvaluator.h" />
|
||||||
|
<ClInclude Include="Pathfinding\Actions\ISpecialAction.h" />
|
||||||
<ClInclude Include="Pathfinding\AINodeStorage.h" />
|
<ClInclude Include="Pathfinding\AINodeStorage.h" />
|
||||||
<ClInclude Include="Pathfinding\AIPathfinder.h" />
|
<ClInclude Include="Pathfinding\AIPathfinder.h" />
|
||||||
<ClInclude Include="Pathfinding\AIPathfinderConfig.h" />
|
<ClInclude Include="Pathfinding\AIPathfinderConfig.h" />
|
||||||
<ClInclude Include="Pathfinding\PathfindingManager.h" />
|
<ClInclude Include="Pathfinding\PathfindingManager.h" />
|
||||||
|
<ClInclude Include="Pathfinding\Rules\AILayerTransitionRule.h" />
|
||||||
|
<ClInclude Include="Pathfinding\Rules\AIMovementAfterDestinationRule.h" />
|
||||||
|
<ClInclude Include="Pathfinding\Rules\AIMovementToDestinationRule.h" />
|
||||||
|
<ClInclude Include="Pathfinding\Rules\AIPreviousNodeRule.h" />
|
||||||
<ClInclude Include="ResourceManager.h" />
|
<ClInclude Include="ResourceManager.h" />
|
||||||
<ClInclude Include="SectorMap.h" />
|
<ClInclude Include="SectorMap.h" />
|
||||||
<ClInclude Include="StdInc.h" />
|
<ClInclude Include="StdInc.h" />
|
||||||
|
@ -90,6 +90,15 @@
|
|||||||
<ClCompile Include="Goals\AdventureSpellCast.cpp">
|
<ClCompile Include="Goals\AdventureSpellCast.cpp">
|
||||||
<Filter>Goals</Filter>
|
<Filter>Goals</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="Pathfinding\Actions\BoatActions.cpp">
|
||||||
|
<Filter>Pathfinding\Actions</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="Pathfinding\Actions\TownPortalAction.cpp" />
|
||||||
|
<ClCompile Include="Pathfinding\Actions\BattleAction.cpp" />
|
||||||
|
<ClCompile Include="Pathfinding\Rules\AILayerTransitionRule.cpp" />
|
||||||
|
<ClCompile Include="Pathfinding\Rules\AIMovementAfterDestinationRule.cpp" />
|
||||||
|
<ClCompile Include="Pathfinding\Rules\AIMovementToDestinationRule.cpp" />
|
||||||
|
<ClCompile Include="Pathfinding\Rules\AIPreviousNodeRule.cpp" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="AIhelper.h" />
|
<ClInclude Include="AIhelper.h" />
|
||||||
@ -189,6 +198,16 @@
|
|||||||
<ClInclude Include="Goals\AdventureSpellCast.h">
|
<ClInclude Include="Goals\AdventureSpellCast.h">
|
||||||
<Filter>Goals</Filter>
|
<Filter>Goals</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="Pathfinding\Actions\ISpecialAction.h">
|
||||||
|
<Filter>Pathfinding\Actions</Filter>
|
||||||
|
</ClInclude>
|
||||||
|
<ClInclude Include="Pathfinding\Actions\TownPortalAction.h" />
|
||||||
|
<ClInclude Include="Pathfinding\Actions\BattleAction.h" />
|
||||||
|
<ClInclude Include="Pathfinding\Actions\BoatActions.h" />
|
||||||
|
<ClInclude Include="Pathfinding\Rules\AILayerTransitionRule.h" />
|
||||||
|
<ClInclude Include="Pathfinding\Rules\AIMovementAfterDestinationRule.h" />
|
||||||
|
<ClInclude Include="Pathfinding\Rules\AIMovementToDestinationRule.h" />
|
||||||
|
<ClInclude Include="Pathfinding\Rules\AIPreviousNodeRule.h" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Filter Include="Pathfinding">
|
<Filter Include="Pathfinding">
|
||||||
@ -197,5 +216,11 @@
|
|||||||
<Filter Include="Goals">
|
<Filter Include="Goals">
|
||||||
<UniqueIdentifier>{f97140a0-eee3-456f-b586-4b13265c01da}</UniqueIdentifier>
|
<UniqueIdentifier>{f97140a0-eee3-456f-b586-4b13265c01da}</UniqueIdentifier>
|
||||||
</Filter>
|
</Filter>
|
||||||
|
<Filter Include="Pathfinding\Rules">
|
||||||
|
<UniqueIdentifier>{beabfdb9-2e76-4daa-8d1a-81086387f319}</UniqueIdentifier>
|
||||||
|
</Filter>
|
||||||
|
<Filter Include="Pathfinding\Actions">
|
||||||
|
<UniqueIdentifier>{3ebb4852-a986-447a-b5cc-20992df76f0c}</UniqueIdentifier>
|
||||||
|
</Filter>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
Loading…
Reference in New Issue
Block a user