mirror of
https://github.com/vcmi/vcmi.git
synced 2024-11-24 08:32:34 +02:00
AI: add ExecuteChain goal
This commit is contained in:
parent
37434dc4cf
commit
ffa626dc2f
@ -149,6 +149,11 @@ std::vector<AIPath> AIhelper::getPathsToTile(const HeroPtr & hero, const int3 &
|
|||||||
return pathfindingManager->getPathsToTile(hero, tile);
|
return pathfindingManager->getPathsToTile(hero, tile);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<AIPath> AIhelper::getPathsToTile(const int3 & tile) const
|
||||||
|
{
|
||||||
|
return pathfindingManager->getPathsToTile(tile);
|
||||||
|
}
|
||||||
|
|
||||||
void AIhelper::updatePaths(std::vector<HeroPtr> heroes, bool useHeroChain)
|
void AIhelper::updatePaths(std::vector<HeroPtr> heroes, bool useHeroChain)
|
||||||
{
|
{
|
||||||
pathfindingManager->updatePaths(heroes, useHeroChain);
|
pathfindingManager->updatePaths(heroes, useHeroChain);
|
||||||
|
@ -62,6 +62,7 @@ public:
|
|||||||
Goals::TGoalVec howToVisitTile(const int3 & tile, bool allowGatherArmy = true) const override;
|
Goals::TGoalVec howToVisitTile(const int3 & tile, bool allowGatherArmy = true) const override;
|
||||||
Goals::TGoalVec howToVisitObj(ObjectIdRef obj, bool allowGatherArmy = true) const override;
|
Goals::TGoalVec howToVisitObj(ObjectIdRef obj, bool allowGatherArmy = true) const override;
|
||||||
std::vector<AIPath> getPathsToTile(const HeroPtr & hero, const int3 & tile) const override;
|
std::vector<AIPath> getPathsToTile(const HeroPtr & hero, const int3 & tile) const override;
|
||||||
|
std::vector<AIPath> getPathsToTile(const int3 & tile) const override;
|
||||||
void updatePaths(std::vector<HeroPtr> heroes, bool useHeroChain = false) override;
|
void updatePaths(std::vector<HeroPtr> heroes, bool useHeroChain = false) override;
|
||||||
|
|
||||||
STRONG_INLINE
|
STRONG_INLINE
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
#include "StdInc.h"
|
#include "StdInc.h"
|
||||||
#include "../VCAI.h"
|
#include "../VCAI.h"
|
||||||
#include "../AIhelper.h"
|
#include "../AIhelper.h"
|
||||||
|
#include "../Goals/ExecuteHeroChain.h"
|
||||||
#include "CaptureObjectsBehavior.h"
|
#include "CaptureObjectsBehavior.h"
|
||||||
#include "../AIUtility.h"
|
#include "../AIUtility.h"
|
||||||
#include "lib/mapping/CMap.h" //for victory conditions
|
#include "lib/mapping/CMap.h" //for victory conditions
|
||||||
@ -38,32 +39,51 @@ Goals::TGoalVec CaptureObjectsBehavior::getTasks() {
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
const int3 pos = objToVisit->visitablePos();
|
const int3 pos = objToVisit->visitablePos();
|
||||||
Goals::TGoalVec waysToVisitObj = ai->ah->howToVisitObj(objToVisit, false);
|
auto paths = ai->ah->getPathsToTile(pos);
|
||||||
|
std::vector<std::shared_ptr<ExecuteHeroChain>> waysToVisitObj;
|
||||||
|
std::shared_ptr<ExecuteHeroChain> closestWay;
|
||||||
|
|
||||||
vstd::erase_if(waysToVisitObj, [objToVisit](Goals::TSubgoal goal) -> bool
|
for(auto & path : paths)
|
||||||
{
|
{
|
||||||
return !goal->hero.validAndSet()
|
#ifdef VCMI_TRACE_PATHFINDER
|
||||||
|| !shouldVisit(goal->hero, objToVisit);
|
std::stringstream str;
|
||||||
});
|
|
||||||
|
|
||||||
|
str << "Path found ";
|
||||||
|
|
||||||
|
for(auto node : path.nodes)
|
||||||
|
str << node.targetHero->name << "->" << node.coord.toString() << "; ";
|
||||||
|
|
||||||
|
logAi->trace(str.str());
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if(!shouldVisit(path.targetHero, objToVisit))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
auto hero = path.targetHero;
|
||||||
|
auto danger = path.getTotalDanger(hero);
|
||||||
|
|
||||||
|
if(isSafeToVisit(hero, path.heroArmy, danger))
|
||||||
|
{
|
||||||
|
auto newWay = std::make_shared<ExecuteHeroChain>(path, objToVisit);
|
||||||
|
|
||||||
|
waysToVisitObj.push_back(newWay);
|
||||||
|
|
||||||
|
if(!closestWay || closestWay->evaluationContext.movementCost > newWay->evaluationContext.movementCost)
|
||||||
|
closestWay = newWay;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if(waysToVisitObj.empty())
|
if(waysToVisitObj.empty())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
Goals::TSubgoal closestWay = *vstd::minElementByFun(waysToVisitObj, [](Goals::TSubgoal goal) -> float {
|
for(auto way : waysToVisitObj)
|
||||||
return goal->evaluationContext.movementCost;
|
|
||||||
});
|
|
||||||
|
|
||||||
for(Goals::TSubgoal way : waysToVisitObj)
|
|
||||||
{
|
{
|
||||||
if(!way->hero->movement)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
way->evaluationContext.closestWayRatio
|
way->evaluationContext.closestWayRatio
|
||||||
= way->evaluationContext.movementCost / closestWay->evaluationContext.movementCost;
|
= way->evaluationContext.movementCost / closestWay->evaluationContext.movementCost;
|
||||||
|
|
||||||
logAi->trace("Behavior %s found %s(%s), danger %d", toString(), way->name(), way->tile.toString(), way->evaluationContext.danger);
|
logAi->trace("Behavior %s found %s(%s), danger %d", toString(), way->name(), way->tile.toString(), way->evaluationContext.danger);
|
||||||
|
|
||||||
tasks.push_back(way);
|
tasks.push_back(sptr(*way));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -52,6 +52,7 @@ set(VCAI_SRCS
|
|||||||
Goals/GetArtOfType.cpp
|
Goals/GetArtOfType.cpp
|
||||||
Goals/FindObj.cpp
|
Goals/FindObj.cpp
|
||||||
Goals/CompleteQuest.cpp
|
Goals/CompleteQuest.cpp
|
||||||
|
Goals/ExecuteHeroChain.cpp
|
||||||
Engine/Nullkiller.cpp
|
Engine/Nullkiller.cpp
|
||||||
Engine/PriorityEvaluator.cpp
|
Engine/PriorityEvaluator.cpp
|
||||||
Behaviors/Behavior.cpp
|
Behaviors/Behavior.cpp
|
||||||
@ -111,6 +112,7 @@ set(VCAI_HEADERS
|
|||||||
Goals/GetArtOfType.h
|
Goals/GetArtOfType.h
|
||||||
Goals/FindObj.h
|
Goals/FindObj.h
|
||||||
Goals/CompleteQuest.h
|
Goals/CompleteQuest.h
|
||||||
|
Goals/ExecuteHeroChain.h
|
||||||
Goals/Goals.h
|
Goals/Goals.h
|
||||||
Engine/Nullkiller.h
|
Engine/Nullkiller.h
|
||||||
Engine/PriorityEvaluator.h
|
Engine/PriorityEvaluator.h
|
||||||
|
@ -14,6 +14,7 @@ public:
|
|||||||
Nullkiller();
|
Nullkiller();
|
||||||
void makeTurn();
|
void makeTurn();
|
||||||
bool isActive(const CGHeroInstance * hero) const { return activeHero.h == hero; }
|
bool isActive(const CGHeroInstance * hero) const { return activeHero.h == hero; }
|
||||||
|
void setActive(const HeroPtr & hero) { activeHero = hero; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Goals::TSubgoal choseBestTask(Behavior & behavior);
|
Goals::TSubgoal choseBestTask(Behavior & behavior);
|
||||||
|
@ -64,7 +64,8 @@ namespace Goals
|
|||||||
TRADE, //val resID at object objid
|
TRADE, //val resID at object objid
|
||||||
BUILD_BOAT,
|
BUILD_BOAT,
|
||||||
COMPLETE_QUEST,
|
COMPLETE_QUEST,
|
||||||
ADVENTURE_SPELL_CAST
|
ADVENTURE_SPELL_CAST,
|
||||||
|
EXECUTE_HERO_CHAIN
|
||||||
};
|
};
|
||||||
|
|
||||||
class DLL_EXPORT TSubgoal : public std::shared_ptr<AbstractGoal>
|
class DLL_EXPORT TSubgoal : public std::shared_ptr<AbstractGoal>
|
||||||
|
111
AI/Nullkiller/Goals/ExecuteHeroChain.cpp
Normal file
111
AI/Nullkiller/Goals/ExecuteHeroChain.cpp
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
/*
|
||||||
|
* ExecuteHeroChain.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 "ExecuteHeroChain.h"
|
||||||
|
#include "VisitTile.h"
|
||||||
|
#include "../VCAI.h"
|
||||||
|
#include "../FuzzyHelper.h"
|
||||||
|
#include "../AIhelper.h"
|
||||||
|
#include "../../lib/mapping/CMap.h" //for victory conditions
|
||||||
|
#include "../../lib/CPathfinder.h"
|
||||||
|
#include "../Engine/Nullkiller.h"
|
||||||
|
|
||||||
|
extern boost::thread_specific_ptr<CCallback> cb;
|
||||||
|
extern boost::thread_specific_ptr<VCAI> ai;
|
||||||
|
extern FuzzyHelper * fh;
|
||||||
|
|
||||||
|
using namespace Goals;
|
||||||
|
|
||||||
|
ExecuteHeroChain::ExecuteHeroChain(const AIPath & path, const CGObjectInstance * obj)
|
||||||
|
:CGoal(Goals::EXECUTE_HERO_CHAIN), chainPath(path)
|
||||||
|
{
|
||||||
|
if(obj)
|
||||||
|
objid = obj->id.getNum();
|
||||||
|
|
||||||
|
evaluationContext.danger = path.getTotalDanger(hero);
|
||||||
|
evaluationContext.movementCost = path.movementCost();
|
||||||
|
evaluationContext.armyLoss = path.armyLoss;
|
||||||
|
evaluationContext.heroStrength = path.getHeroStrength();
|
||||||
|
hero = path.targetHero;
|
||||||
|
tile = path.firstTileToGet();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ExecuteHeroChain::operator==(const ExecuteHeroChain & other) const
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
TSubgoal ExecuteHeroChain::whatToDoToAchieve()
|
||||||
|
{
|
||||||
|
return iAmElementar();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ExecuteHeroChain::accept(VCAI * ai)
|
||||||
|
{
|
||||||
|
logAi->debug("Executing hero chain towards %s", tile.toString());
|
||||||
|
|
||||||
|
#ifdef VCMI_TRACE_PATHFINDER
|
||||||
|
std::stringstream str;
|
||||||
|
|
||||||
|
str << "Path ";
|
||||||
|
|
||||||
|
for(auto node : chainPath.nodes)
|
||||||
|
str << node.targetHero->name << "->" << node.coord.toString() << "; ";
|
||||||
|
|
||||||
|
logAi->trace(str.str());
|
||||||
|
#endif
|
||||||
|
|
||||||
|
std::set<int> blockedIndexes;
|
||||||
|
|
||||||
|
for(int i = chainPath.nodes.size() - 1; i >= 0; i--)
|
||||||
|
{
|
||||||
|
auto & node = chainPath.nodes[i];
|
||||||
|
|
||||||
|
HeroPtr hero = node.targetHero;
|
||||||
|
auto vt = Goals::sptr(Goals::VisitTile(node.coord).sethero(hero));
|
||||||
|
|
||||||
|
if(vstd::contains(blockedIndexes, i))
|
||||||
|
{
|
||||||
|
blockedIndexes.insert(node.parentIndex);
|
||||||
|
ai->setGoal(hero, vt);
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
logAi->debug("Moving hero %s to %s", hero.name, node.coord.toString());
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
ai->nullkiller->setActive(hero);
|
||||||
|
vt->accept(ai);
|
||||||
|
|
||||||
|
blockedIndexes.insert(node.parentIndex);
|
||||||
|
}
|
||||||
|
catch(goalFulfilledException)
|
||||||
|
{
|
||||||
|
if(!hero)
|
||||||
|
{
|
||||||
|
logAi->debug("Hero %s was killed while attempting to rich %s", hero.name, node.coord.toString());
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string ExecuteHeroChain::name() const
|
||||||
|
{
|
||||||
|
return "ExecuteHeroChain";
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string ExecuteHeroChain::completeMessage() const
|
||||||
|
{
|
||||||
|
return "Hero chain completed";
|
||||||
|
}
|
35
AI/Nullkiller/Goals/ExecuteHeroChain.h
Normal file
35
AI/Nullkiller/Goals/ExecuteHeroChain.h
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
/*
|
||||||
|
* ExecuteHeroChain.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 "CGoal.h"
|
||||||
|
|
||||||
|
namespace Goals
|
||||||
|
{
|
||||||
|
class DLL_EXPORT ExecuteHeroChain : public CGoal<ExecuteHeroChain>
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
AIPath chainPath;
|
||||||
|
|
||||||
|
public:
|
||||||
|
ExecuteHeroChain(const AIPath & path, const CGObjectInstance * obj = nullptr);
|
||||||
|
|
||||||
|
TGoalVec getAllPossibleSubgoals() override
|
||||||
|
{
|
||||||
|
return TGoalVec();
|
||||||
|
}
|
||||||
|
|
||||||
|
TSubgoal whatToDoToAchieve() override;
|
||||||
|
void accept(VCAI * ai) override;
|
||||||
|
std::string name() const override;
|
||||||
|
std::string completeMessage() const override;
|
||||||
|
virtual bool operator==(const ExecuteHeroChain & other) const override;
|
||||||
|
};
|
||||||
|
}
|
@ -731,7 +731,7 @@ std::vector<AIPath> AINodeStorage::getChainInfo(const int3 & pos, bool isOnLand)
|
|||||||
path.targetObjectDanger = evaluateDanger(pos, path.targetHero);
|
path.targetObjectDanger = evaluateDanger(pos, path.targetHero);
|
||||||
path.chainMask = node.actor->chainMask;
|
path.chainMask = node.actor->chainMask;
|
||||||
|
|
||||||
fillChainInfo(&node, path);
|
fillChainInfo(&node, path, -1);
|
||||||
|
|
||||||
paths.push_back(path);
|
paths.push_back(path);
|
||||||
}
|
}
|
||||||
@ -739,7 +739,7 @@ std::vector<AIPath> AINodeStorage::getChainInfo(const int3 & pos, bool isOnLand)
|
|||||||
return paths;
|
return paths;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AINodeStorage::fillChainInfo(const AIPathNode * node, AIPath & path) const
|
void AINodeStorage::fillChainInfo(const AIPathNode * node, AIPath & path, int parentIndex) const
|
||||||
{
|
{
|
||||||
while(node != nullptr)
|
while(node != nullptr)
|
||||||
{
|
{
|
||||||
@ -747,7 +747,7 @@ void AINodeStorage::fillChainInfo(const AIPathNode * node, AIPath & path) const
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
if(node->chainOther)
|
if(node->chainOther)
|
||||||
fillChainInfo(node->chainOther, path);
|
fillChainInfo(node->chainOther, path, parentIndex);
|
||||||
|
|
||||||
if(node->actor->hero->visitablePos() != node->coord)
|
if(node->actor->hero->visitablePos() != node->coord)
|
||||||
{
|
{
|
||||||
@ -757,6 +757,9 @@ void AINodeStorage::fillChainInfo(const AIPathNode * node, AIPath & path) const
|
|||||||
pathNode.turns = node->turns;
|
pathNode.turns = node->turns;
|
||||||
pathNode.danger = node->danger;
|
pathNode.danger = node->danger;
|
||||||
pathNode.coord = node->coord;
|
pathNode.coord = node->coord;
|
||||||
|
pathNode.parentIndex = parentIndex;
|
||||||
|
|
||||||
|
parentIndex = path.nodes.size();
|
||||||
|
|
||||||
path.nodes.push_back(pathNode);
|
path.nodes.push_back(pathNode);
|
||||||
}
|
}
|
||||||
|
@ -39,6 +39,7 @@ struct AIPathNodeInfo
|
|||||||
int3 coord;
|
int3 coord;
|
||||||
uint64_t danger;
|
uint64_t danger;
|
||||||
const CGHeroInstance * targetHero;
|
const CGHeroInstance * targetHero;
|
||||||
|
int parentIndex;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct AIPath
|
struct AIPath
|
||||||
@ -158,7 +159,7 @@ private:
|
|||||||
void addHeroChain(const std::vector<ExchangeCandidate> & result);
|
void addHeroChain(const std::vector<ExchangeCandidate> & result);
|
||||||
|
|
||||||
void calculateTownPortalTeleportations(const PathNodeInfo & source, std::vector<CGPathNode *> & neighbours);
|
void calculateTownPortalTeleportations(const PathNodeInfo & source, std::vector<CGPathNode *> & neighbours);
|
||||||
void fillChainInfo(const AIPathNode * node, AIPath & path) const;
|
void fillChainInfo(const AIPathNode * node, AIPath & path, int parentIndex) const;
|
||||||
void commit(
|
void commit(
|
||||||
AIPathNode * destination,
|
AIPathNode * destination,
|
||||||
const AIPathNode * source,
|
const AIPathNode * source,
|
||||||
|
@ -31,7 +31,7 @@ bool AIPathfinder::isTileAccessible(const HeroPtr & hero, const int3 & tile) con
|
|||||||
|| storage->isTileAccessible(hero, tile, EPathfindingLayer::SAIL);
|
|| storage->isTileAccessible(hero, tile, EPathfindingLayer::SAIL);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<AIPath> AIPathfinder::getPathInfo(const HeroPtr & hero, const int3 & tile) const
|
std::vector<AIPath> AIPathfinder::getPathInfo(const int3 & tile) const
|
||||||
{
|
{
|
||||||
const TerrainTile * tileInfo = cb->getTile(tile, false);
|
const TerrainTile * tileInfo = cb->getTile(tile, false);
|
||||||
|
|
||||||
|
@ -23,7 +23,7 @@ private:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
AIPathfinder(CPlayerSpecificInfoCallback * cb, VCAI * ai);
|
AIPathfinder(CPlayerSpecificInfoCallback * cb, VCAI * ai);
|
||||||
std::vector<AIPath> getPathInfo(const HeroPtr & hero, const int3 & tile) const;
|
std::vector<AIPath> getPathInfo(const int3 & tile) const;
|
||||||
bool isTileAccessible(const HeroPtr & hero, const int3 & tile) const;
|
bool isTileAccessible(const HeroPtr & hero, const int3 & tile) const;
|
||||||
void updatePaths(std::vector<HeroPtr> heroes, bool useHeroChain = false);
|
void updatePaths(std::vector<HeroPtr> heroes, bool useHeroChain = false);
|
||||||
void init();
|
void init();
|
||||||
|
@ -104,7 +104,18 @@ Goals::TGoalVec PathfindingManager::howToVisitObj(const HeroPtr & hero, ObjectId
|
|||||||
|
|
||||||
std::vector<AIPath> PathfindingManager::getPathsToTile(const HeroPtr & hero, const int3 & tile) const
|
std::vector<AIPath> PathfindingManager::getPathsToTile(const HeroPtr & hero, const int3 & tile) const
|
||||||
{
|
{
|
||||||
return pathfinder->getPathInfo(hero, tile);
|
auto paths = pathfinder->getPathInfo(tile);
|
||||||
|
|
||||||
|
vstd::erase_if(paths, [&](AIPath & path) -> bool{
|
||||||
|
return path.targetHero != hero.h;
|
||||||
|
});
|
||||||
|
|
||||||
|
return paths;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<AIPath> PathfindingManager::getPathsToTile(const int3 & tile) const
|
||||||
|
{
|
||||||
|
return pathfinder->getPathInfo(tile);
|
||||||
}
|
}
|
||||||
|
|
||||||
Goals::TGoalVec PathfindingManager::findPaths(
|
Goals::TGoalVec PathfindingManager::findPaths(
|
||||||
@ -117,7 +128,7 @@ Goals::TGoalVec PathfindingManager::findPaths(
|
|||||||
boost::optional<uint64_t> armyValueRequired;
|
boost::optional<uint64_t> armyValueRequired;
|
||||||
uint64_t danger;
|
uint64_t danger;
|
||||||
|
|
||||||
std::vector<AIPath> chainInfo = pathfinder->getPathInfo(hero, dest);
|
std::vector<AIPath> chainInfo = pathfinder->getPathInfo(dest);
|
||||||
|
|
||||||
#ifdef VCMI_TRACE_PATHFINDER
|
#ifdef VCMI_TRACE_PATHFINDER
|
||||||
logAi->trace("Trying to find a way for %s to visit tile %s", hero->name, dest.toString());
|
logAi->trace("Trying to find a way for %s to visit tile %s", hero->name, dest.toString());
|
||||||
|
@ -26,6 +26,7 @@ public:
|
|||||||
virtual Goals::TGoalVec howToVisitTile(const int3 & tile, bool allowGatherArmy = true) const = 0;
|
virtual Goals::TGoalVec howToVisitTile(const int3 & tile, bool allowGatherArmy = true) const = 0;
|
||||||
virtual Goals::TGoalVec howToVisitObj(ObjectIdRef obj, bool allowGatherArmy = true) const = 0;
|
virtual Goals::TGoalVec howToVisitObj(ObjectIdRef obj, bool allowGatherArmy = true) const = 0;
|
||||||
virtual std::vector<AIPath> getPathsToTile(const HeroPtr & hero, const int3 & tile) const = 0;
|
virtual std::vector<AIPath> getPathsToTile(const HeroPtr & hero, const int3 & tile) const = 0;
|
||||||
|
virtual std::vector<AIPath> getPathsToTile(const int3 & tile) const = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
class DLL_EXPORT PathfindingManager : public IPathfindingManager
|
class DLL_EXPORT PathfindingManager : public IPathfindingManager
|
||||||
@ -46,6 +47,7 @@ public:
|
|||||||
Goals::TGoalVec howToVisitTile(const int3 & tile, bool allowGatherArmy = true) const override;
|
Goals::TGoalVec howToVisitTile(const int3 & tile, bool allowGatherArmy = true) const override;
|
||||||
Goals::TGoalVec howToVisitObj(ObjectIdRef obj, bool allowGatherArmy = true) const override;
|
Goals::TGoalVec howToVisitObj(ObjectIdRef obj, bool allowGatherArmy = true) const override;
|
||||||
std::vector<AIPath> getPathsToTile(const HeroPtr & hero, const int3 & tile) const override;
|
std::vector<AIPath> getPathsToTile(const HeroPtr & hero, const int3 & tile) const override;
|
||||||
|
std::vector<AIPath> getPathsToTile(const int3 & tile) const override;
|
||||||
void updatePaths(std::vector<HeroPtr> heroes, bool useHeroChain = false) override;
|
void updatePaths(std::vector<HeroPtr> heroes, bool useHeroChain = false) override;
|
||||||
|
|
||||||
STRONG_INLINE
|
STRONG_INLINE
|
||||||
|
@ -603,7 +603,7 @@ void VCAI::init(std::shared_ptr<CCallback> CB)
|
|||||||
if(!fh)
|
if(!fh)
|
||||||
fh = new FuzzyHelper();
|
fh = new FuzzyHelper();
|
||||||
|
|
||||||
if(playerID.getStr(false) == "green")
|
if(playerID.getStr(false) == "blue")
|
||||||
{
|
{
|
||||||
nullkiller.reset(new Nullkiller());
|
nullkiller.reset(new Nullkiller());
|
||||||
}
|
}
|
||||||
@ -815,16 +815,18 @@ void VCAI::makeTurn()
|
|||||||
{
|
{
|
||||||
nullkiller->makeTurn();
|
nullkiller->makeTurn();
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//it looks messy here, but it's better to have armed heroes before attempting realizing goals
|
||||||
|
for(const CGTownInstance * t : cb->getTownsInfo())
|
||||||
|
moveCreaturesToHero(t);
|
||||||
|
|
||||||
//it looks messy here, but it's better to have armed heroes before attempting realizing goals
|
mainLoop();
|
||||||
for(const CGTownInstance * t : cb->getTownsInfo())
|
|
||||||
moveCreaturesToHero(t);
|
|
||||||
|
|
||||||
mainLoop();
|
/*Below function is also responsible for hero movement via internal wander function. By design it is separate logic for heroes that have nothing to do.
|
||||||
|
Heroes that were not picked by striveToGoal(sptr(Goals::Win())); recently (so they do not have new goals and cannot continue/reevaluate previously locked goals) will do logic in wander().*/
|
||||||
/*Below function is also responsible for hero movement via internal wander function. By design it is separate logic for heroes that have nothing to do.
|
performTypicalActions();
|
||||||
Heroes that were not picked by striveToGoal(sptr(Goals::Win())); recently (so they do not have new goals and cannot continue/reevaluate previously locked goals) will do logic in wander().*/
|
}
|
||||||
performTypicalActions();
|
|
||||||
|
|
||||||
//for debug purpose
|
//for debug purpose
|
||||||
for (auto h : cb->getHeroesInfo())
|
for (auto h : cb->getHeroesInfo())
|
||||||
|
Loading…
Reference in New Issue
Block a user