mirror of
https://github.com/vcmi/vcmi.git
synced 2025-08-13 19:54:17 +02:00
AI: hero chain stabilisation
This commit is contained in:
committed by
Andrii Danylchenko
parent
3a0d9fe14e
commit
0e328ab3c2
@@ -172,6 +172,12 @@ void AINodeStorage::commit(CDestinationNodeInfo & destination, const PathNodeInf
|
|||||||
{
|
{
|
||||||
commit(dstNode, srcNode, destination.action, destination.turn, destination.movementLeft, destination.cost);
|
commit(dstNode, srcNode, destination.action, destination.turn, destination.movementLeft, destination.cost);
|
||||||
|
|
||||||
|
if(srcNode->specialAction || srcNode->chainOther)
|
||||||
|
{
|
||||||
|
// there is some action on source tile which should be performed before we can bypass it
|
||||||
|
destination.node->theNodeBefore = source.node;
|
||||||
|
}
|
||||||
|
|
||||||
if(dstNode->specialAction && dstNode->actor)
|
if(dstNode->specialAction && dstNode->actor)
|
||||||
{
|
{
|
||||||
dstNode->specialAction->applyOnDestination(dstNode->actor->hero, destination, source, dstNode, srcNode);
|
dstNode->specialAction->applyOnDestination(dstNode->actor->hero, destination, source, dstNode, srcNode);
|
||||||
@@ -183,7 +189,7 @@ void AINodeStorage::commit(CDestinationNodeInfo & destination, const PathNodeInf
|
|||||||
source.coord.toString(),
|
source.coord.toString(),
|
||||||
destination.coord.toString(),
|
destination.coord.toString(),
|
||||||
destination.cost,
|
destination.cost,
|
||||||
dstNode->actor->hero->name,
|
dstNode->actor->toString(),
|
||||||
dstNode->actor->chainMask);
|
dstNode->actor->chainMask);
|
||||||
#endif
|
#endif
|
||||||
});
|
});
|
||||||
@@ -251,14 +257,20 @@ bool AINodeStorage::calculateHeroChain()
|
|||||||
|
|
||||||
for(AIPathNode & node : chains)
|
for(AIPathNode & node : chains)
|
||||||
{
|
{
|
||||||
|
if(node.coord.x == 60 && node.coord.y == 56 && node.actor)
|
||||||
|
logAi->trace(node.actor->toString());
|
||||||
|
|
||||||
if(node.turns <= heroChainMaxTurns && node.action != CGPathNode::ENodeAction::UNKNOWN)
|
if(node.turns <= heroChainMaxTurns && node.action != CGPathNode::ENodeAction::UNKNOWN)
|
||||||
buffer.push_back(&node);
|
buffer.push_back(&node);
|
||||||
}
|
}
|
||||||
|
|
||||||
for(AIPathNode * node : buffer)
|
for(AIPathNode * node : buffer)
|
||||||
|
{
|
||||||
|
if(node->actor->hero)
|
||||||
{
|
{
|
||||||
addHeroChain(node, buffer);
|
addHeroChain(node, buffer);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return heroChain.size();
|
return heroChain.size();
|
||||||
@@ -277,9 +289,9 @@ void AINodeStorage::addHeroChain(AIPathNode * srcNode, std::vector<AIPathNode *>
|
|||||||
#ifdef VCMI_TRACE_PATHFINDER_EX
|
#ifdef VCMI_TRACE_PATHFINDER_EX
|
||||||
logAi->trace(
|
logAi->trace(
|
||||||
"Thy exchange %s[%i] -> %s[%i] at %s",
|
"Thy exchange %s[%i] -> %s[%i] at %s",
|
||||||
node->actor->hero->name,
|
node->actor->toString(),
|
||||||
node->actor->chainMask,
|
node->actor->chainMask,
|
||||||
srcNode->actor->hero->name,
|
srcNode->actor->toString(),
|
||||||
srcNode->actor->chainMask,
|
srcNode->actor->chainMask,
|
||||||
srcNode->coord.toString());
|
srcNode->coord.toString());
|
||||||
#endif
|
#endif
|
||||||
@@ -299,9 +311,9 @@ void AINodeStorage::addHeroChain(AIPathNode * carrier, AIPathNode * other)
|
|||||||
#ifdef VCMI_TRACE_PATHFINDER_EX
|
#ifdef VCMI_TRACE_PATHFINDER_EX
|
||||||
logAi->trace(
|
logAi->trace(
|
||||||
"Exchange allowed %s[%i] -> %s[%i] at %s",
|
"Exchange allowed %s[%i] -> %s[%i] at %s",
|
||||||
other->actor->hero->name,
|
other->actor->toString(),
|
||||||
other->actor->chainMask,
|
other->actor->chainMask,
|
||||||
carrier->actor->hero->name,
|
carrier->actor->toString(),
|
||||||
carrier->actor->chainMask,
|
carrier->actor->chainMask,
|
||||||
carrier->coord.toString());
|
carrier->coord.toString());
|
||||||
#endif
|
#endif
|
||||||
@@ -344,8 +356,8 @@ void AINodeStorage::addHeroChain(AIPathNode * carrier, AIPathNode * other)
|
|||||||
logAi->trace(
|
logAi->trace(
|
||||||
"Chain accepted at %s %s -> %s, mask %i, cost %f",
|
"Chain accepted at %s %s -> %s, mask %i, cost %f",
|
||||||
chainNode->coord.toString(),
|
chainNode->coord.toString(),
|
||||||
other->actor->hero->name,
|
other->actor->toString(),
|
||||||
chainNode->actor->hero->name,
|
chainNode->actor->toString(),
|
||||||
chainNode->actor->chainMask,
|
chainNode->actor->chainMask,
|
||||||
chainNode->cost);
|
chainNode->cost);
|
||||||
#endif
|
#endif
|
||||||
@@ -430,7 +442,7 @@ void AINodeStorage::setHeroes(std::vector<HeroPtr> heroes, const VCAI * _ai)
|
|||||||
|
|
||||||
void AINodeStorage::setTownsAndDwellings(
|
void AINodeStorage::setTownsAndDwellings(
|
||||||
const std::vector<const CGTownInstance *> & towns,
|
const std::vector<const CGTownInstance *> & towns,
|
||||||
const std::vector<const CGObjectInstance *> & visitableObjs)
|
const std::set<const CGObjectInstance *> & visitableObjs)
|
||||||
{
|
{
|
||||||
for(auto town : towns)
|
for(auto town : towns)
|
||||||
{
|
{
|
||||||
|
@@ -85,7 +85,7 @@ private:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
/// more than 1 chain layer for each hero allows us to have more than 1 path to each tile so we can chose more optimal one.
|
/// more than 1 chain layer for each hero allows us to have more than 1 path to each tile so we can chose more optimal one.
|
||||||
static const int NUM_CHAINS = 3 * GameConstants::MAX_HEROES_PER_PLAYER;
|
static const int NUM_CHAINS = 5 * GameConstants::MAX_HEROES_PER_PLAYER;
|
||||||
|
|
||||||
AINodeStorage(const int3 & sizes);
|
AINodeStorage(const int3 & sizes);
|
||||||
~AINodeStorage();
|
~AINodeStorage();
|
||||||
@@ -116,7 +116,7 @@ public:
|
|||||||
void setHeroes(std::vector<HeroPtr> heroes, const VCAI * ai);
|
void setHeroes(std::vector<HeroPtr> heroes, const VCAI * ai);
|
||||||
void setTownsAndDwellings(
|
void setTownsAndDwellings(
|
||||||
const std::vector<const CGTownInstance *> & towns,
|
const std::vector<const CGTownInstance *> & towns,
|
||||||
const std::vector<const CGObjectInstance *> & visitableObjs);
|
const std::set<const CGObjectInstance *> & visitableObjs);
|
||||||
const CGHeroInstance * getHero(const CGPathNode * node) const;
|
const CGHeroInstance * getHero(const CGPathNode * node) const;
|
||||||
const std::set<const CGHeroInstance *> getAllHeroes() const;
|
const std::set<const CGHeroInstance *> getAllHeroes() const;
|
||||||
void clear();
|
void clear();
|
||||||
|
@@ -56,6 +56,11 @@ void AIPathfinder::updatePaths(std::vector<HeroPtr> heroes, bool useHeroChain)
|
|||||||
storage->clear();
|
storage->clear();
|
||||||
storage->setHeroes(heroes, ai);
|
storage->setHeroes(heroes, ai);
|
||||||
|
|
||||||
|
if(useHeroChain)
|
||||||
|
{
|
||||||
|
storage->setTownsAndDwellings(cb->getTownsInfo(), ai->visitableObjs);
|
||||||
|
}
|
||||||
|
|
||||||
auto config = std::make_shared<AIPathfinding::AIPathfinderConfig>(cb, ai, storage);
|
auto config = std::make_shared<AIPathfinding::AIPathfinderConfig>(cb, ai, storage);
|
||||||
|
|
||||||
do {
|
do {
|
||||||
|
@@ -16,23 +16,6 @@
|
|||||||
#include "../../../lib/mapping/CMap.h"
|
#include "../../../lib/mapping/CMap.h"
|
||||||
#include "../../../lib/mapObjects/MapObjects.h"
|
#include "../../../lib/mapObjects/MapObjects.h"
|
||||||
|
|
||||||
class ExchangeAction : public ISpecialAction
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
const CGHeroInstance * target;
|
|
||||||
const CGHeroInstance * source;
|
|
||||||
|
|
||||||
public:
|
|
||||||
ExchangeAction(const CGHeroInstance * target, const CGHeroInstance * source)
|
|
||||||
:target(target), source(source)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
virtual Goals::TSubgoal whatToDo(const HeroPtr & hero) const override
|
|
||||||
{
|
|
||||||
return Goals::sptr(Goals::VisitHero(target->id.getNum()).sethero(hero));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
ChainActor::ChainActor(const CGHeroInstance * hero, uint64_t chainMask)
|
ChainActor::ChainActor(const CGHeroInstance * hero, uint64_t chainMask)
|
||||||
:hero(hero), isMovable(true), chainMask(chainMask), creatureSet(hero),
|
:hero(hero), isMovable(true), chainMask(chainMask), creatureSet(hero),
|
||||||
baseActor(this), carrierParent(nullptr), otherParent(nullptr)
|
baseActor(this), carrierParent(nullptr), otherParent(nullptr)
|
||||||
@@ -60,6 +43,11 @@ ChainActor::ChainActor(const CGObjectInstance * obj, const CCreatureSet * creatu
|
|||||||
armyValue = creatureSet->getArmyStrength();
|
armyValue = creatureSet->getArmyStrength();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string ChainActor::toString() const
|
||||||
|
{
|
||||||
|
return hero->name;
|
||||||
|
}
|
||||||
|
|
||||||
HeroActor::HeroActor(const CGHeroInstance * hero, uint64_t chainMask, const VCAI * ai)
|
HeroActor::HeroActor(const CGHeroInstance * hero, uint64_t chainMask, const VCAI * ai)
|
||||||
:ChainActor(hero, chainMask)
|
:ChainActor(hero, chainMask)
|
||||||
{
|
{
|
||||||
@@ -213,7 +201,8 @@ DwellingActor::DwellingActor(const CGDwelling * dwelling, uint64_t chainMask, bo
|
|||||||
dwelling,
|
dwelling,
|
||||||
getDwellingCreatures(dwelling, waitForGrowth),
|
getDwellingCreatures(dwelling, waitForGrowth),
|
||||||
chainMask,
|
chainMask,
|
||||||
getInitialTurn(waitForGrowth, dayOfWeek))
|
getInitialTurn(waitForGrowth, dayOfWeek)),
|
||||||
|
dwelling(dwelling)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -230,6 +219,11 @@ int DwellingActor::getInitialTurn(bool waitForGrowth, int dayOfWeek)
|
|||||||
return 8 - dayOfWeek;
|
return 8 - dayOfWeek;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string DwellingActor::toString() const
|
||||||
|
{
|
||||||
|
return dwelling->typeName + dwelling->visitablePos().toString();
|
||||||
|
}
|
||||||
|
|
||||||
CCreatureSet * DwellingActor::getDwellingCreatures(const CGDwelling * dwelling, bool waitForGrowth)
|
CCreatureSet * DwellingActor::getDwellingCreatures(const CGDwelling * dwelling, bool waitForGrowth)
|
||||||
{
|
{
|
||||||
CCreatureSet * dwellingCreatures = new CCreatureSet();
|
CCreatureSet * dwellingCreatures = new CCreatureSet();
|
||||||
@@ -259,6 +253,11 @@ CCreatureSet * DwellingActor::getDwellingCreatures(const CGDwelling * dwelling,
|
|||||||
}
|
}
|
||||||
|
|
||||||
TownGarrisonActor::TownGarrisonActor(const CGTownInstance * town, uint64_t chainMask)
|
TownGarrisonActor::TownGarrisonActor(const CGTownInstance * town, uint64_t chainMask)
|
||||||
:ChainActor(town, town->getUpperArmy(), chainMask, 0)
|
:ChainActor(town, town->getUpperArmy(), chainMask, 0), town(town)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string TownGarrisonActor::toString() const
|
||||||
|
{
|
||||||
|
return town->name;
|
||||||
|
}
|
@@ -48,6 +48,7 @@ public:
|
|||||||
ChainActor(){}
|
ChainActor(){}
|
||||||
|
|
||||||
virtual bool canExchange(const ChainActor * other) const;
|
virtual bool canExchange(const ChainActor * other) const;
|
||||||
|
virtual std::string toString() const;
|
||||||
ChainActor * exchange(const ChainActor * other) const { return exchange(this, other); }
|
ChainActor * exchange(const ChainActor * other) const { return exchange(this, other); }
|
||||||
void setBaseActor(HeroActor * base);
|
void setBaseActor(HeroActor * base);
|
||||||
|
|
||||||
@@ -102,9 +103,13 @@ protected:
|
|||||||
|
|
||||||
class DwellingActor : public ChainActor
|
class DwellingActor : public ChainActor
|
||||||
{
|
{
|
||||||
|
private:
|
||||||
|
const CGDwelling * dwelling;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
DwellingActor(const CGDwelling * dwelling, uint64_t chainMask, bool waitForGrowth, int dayOfWeek);
|
DwellingActor(const CGDwelling * dwelling, uint64_t chainMask, bool waitForGrowth, int dayOfWeek);
|
||||||
~DwellingActor();
|
~DwellingActor();
|
||||||
|
virtual std::string toString() const override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
int getInitialTurn(bool waitForGrowth, int dayOfWeek);
|
int getInitialTurn(bool waitForGrowth, int dayOfWeek);
|
||||||
@@ -113,6 +118,10 @@ protected:
|
|||||||
|
|
||||||
class TownGarrisonActor : public ChainActor
|
class TownGarrisonActor : public ChainActor
|
||||||
{
|
{
|
||||||
|
private:
|
||||||
|
const CGTownInstance * town;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
TownGarrisonActor(const CGTownInstance * town, uint64_t chainMask);
|
TownGarrisonActor(const CGTownInstance * town, uint64_t chainMask);
|
||||||
|
virtual std::string toString() const override;
|
||||||
};
|
};
|
@@ -35,13 +35,5 @@ namespace AIPathfinding
|
|||||||
#endif
|
#endif
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto srcNode = nodeStorage->getAINode(source.node);
|
|
||||||
|
|
||||||
if(srcNode->specialAction || srcNode->chainOther)
|
|
||||||
{
|
|
||||||
// there is some action on source tile which should be performed before we can bypass it
|
|
||||||
destination.node->theNodeBefore = source.node;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user