mirror of
https://github.com/vcmi/vcmi.git
synced 2025-03-25 21:38:59 +02:00
AI: hero chain stabilisation
This commit is contained in:
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);
|
||||
|
||||
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)
|
||||
{
|
||||
dstNode->specialAction->applyOnDestination(dstNode->actor->hero, destination, source, dstNode, srcNode);
|
||||
@ -183,7 +189,7 @@ void AINodeStorage::commit(CDestinationNodeInfo & destination, const PathNodeInf
|
||||
source.coord.toString(),
|
||||
destination.coord.toString(),
|
||||
destination.cost,
|
||||
dstNode->actor->hero->name,
|
||||
dstNode->actor->toString(),
|
||||
dstNode->actor->chainMask);
|
||||
#endif
|
||||
});
|
||||
@ -251,13 +257,19 @@ bool AINodeStorage::calculateHeroChain()
|
||||
|
||||
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)
|
||||
buffer.push_back(&node);
|
||||
}
|
||||
|
||||
for(AIPathNode * node : buffer)
|
||||
{
|
||||
addHeroChain(node, buffer);
|
||||
if(node->actor->hero)
|
||||
{
|
||||
addHeroChain(node, buffer);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@ -277,9 +289,9 @@ void AINodeStorage::addHeroChain(AIPathNode * srcNode, std::vector<AIPathNode *>
|
||||
#ifdef VCMI_TRACE_PATHFINDER_EX
|
||||
logAi->trace(
|
||||
"Thy exchange %s[%i] -> %s[%i] at %s",
|
||||
node->actor->hero->name,
|
||||
node->actor->toString(),
|
||||
node->actor->chainMask,
|
||||
srcNode->actor->hero->name,
|
||||
srcNode->actor->toString(),
|
||||
srcNode->actor->chainMask,
|
||||
srcNode->coord.toString());
|
||||
#endif
|
||||
@ -299,9 +311,9 @@ void AINodeStorage::addHeroChain(AIPathNode * carrier, AIPathNode * other)
|
||||
#ifdef VCMI_TRACE_PATHFINDER_EX
|
||||
logAi->trace(
|
||||
"Exchange allowed %s[%i] -> %s[%i] at %s",
|
||||
other->actor->hero->name,
|
||||
other->actor->toString(),
|
||||
other->actor->chainMask,
|
||||
carrier->actor->hero->name,
|
||||
carrier->actor->toString(),
|
||||
carrier->actor->chainMask,
|
||||
carrier->coord.toString());
|
||||
#endif
|
||||
@ -344,8 +356,8 @@ void AINodeStorage::addHeroChain(AIPathNode * carrier, AIPathNode * other)
|
||||
logAi->trace(
|
||||
"Chain accepted at %s %s -> %s, mask %i, cost %f",
|
||||
chainNode->coord.toString(),
|
||||
other->actor->hero->name,
|
||||
chainNode->actor->hero->name,
|
||||
other->actor->toString(),
|
||||
chainNode->actor->toString(),
|
||||
chainNode->actor->chainMask,
|
||||
chainNode->cost);
|
||||
#endif
|
||||
@ -430,7 +442,7 @@ void AINodeStorage::setHeroes(std::vector<HeroPtr> heroes, const VCAI * _ai)
|
||||
|
||||
void AINodeStorage::setTownsAndDwellings(
|
||||
const std::vector<const CGTownInstance *> & towns,
|
||||
const std::vector<const CGObjectInstance *> & visitableObjs)
|
||||
const std::set<const CGObjectInstance *> & visitableObjs)
|
||||
{
|
||||
for(auto town : towns)
|
||||
{
|
||||
|
@ -85,7 +85,7 @@ private:
|
||||
|
||||
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.
|
||||
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();
|
||||
@ -116,7 +116,7 @@ public:
|
||||
void setHeroes(std::vector<HeroPtr> heroes, const VCAI * ai);
|
||||
void setTownsAndDwellings(
|
||||
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 std::set<const CGHeroInstance *> getAllHeroes() const;
|
||||
void clear();
|
||||
|
@ -56,6 +56,11 @@ void AIPathfinder::updatePaths(std::vector<HeroPtr> heroes, bool useHeroChain)
|
||||
storage->clear();
|
||||
storage->setHeroes(heroes, ai);
|
||||
|
||||
if(useHeroChain)
|
||||
{
|
||||
storage->setTownsAndDwellings(cb->getTownsInfo(), ai->visitableObjs);
|
||||
}
|
||||
|
||||
auto config = std::make_shared<AIPathfinding::AIPathfinderConfig>(cb, ai, storage);
|
||||
|
||||
do {
|
||||
|
@ -16,23 +16,6 @@
|
||||
#include "../../../lib/mapping/CMap.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)
|
||||
:hero(hero), isMovable(true), chainMask(chainMask), creatureSet(hero),
|
||||
baseActor(this), carrierParent(nullptr), otherParent(nullptr)
|
||||
@ -60,6 +43,11 @@ ChainActor::ChainActor(const CGObjectInstance * obj, const CCreatureSet * creatu
|
||||
armyValue = creatureSet->getArmyStrength();
|
||||
}
|
||||
|
||||
std::string ChainActor::toString() const
|
||||
{
|
||||
return hero->name;
|
||||
}
|
||||
|
||||
HeroActor::HeroActor(const CGHeroInstance * hero, uint64_t chainMask, const VCAI * ai)
|
||||
:ChainActor(hero, chainMask)
|
||||
{
|
||||
@ -213,7 +201,8 @@ DwellingActor::DwellingActor(const CGDwelling * dwelling, uint64_t chainMask, bo
|
||||
dwelling,
|
||||
getDwellingCreatures(dwelling, waitForGrowth),
|
||||
chainMask,
|
||||
getInitialTurn(waitForGrowth, dayOfWeek))
|
||||
getInitialTurn(waitForGrowth, dayOfWeek)),
|
||||
dwelling(dwelling)
|
||||
{
|
||||
}
|
||||
|
||||
@ -230,6 +219,11 @@ int DwellingActor::getInitialTurn(bool waitForGrowth, int dayOfWeek)
|
||||
return 8 - dayOfWeek;
|
||||
}
|
||||
|
||||
std::string DwellingActor::toString() const
|
||||
{
|
||||
return dwelling->typeName + dwelling->visitablePos().toString();
|
||||
}
|
||||
|
||||
CCreatureSet * DwellingActor::getDwellingCreatures(const CGDwelling * dwelling, bool waitForGrowth)
|
||||
{
|
||||
CCreatureSet * dwellingCreatures = new CCreatureSet();
|
||||
@ -259,6 +253,11 @@ CCreatureSet * DwellingActor::getDwellingCreatures(const CGDwelling * dwelling,
|
||||
}
|
||||
|
||||
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(){}
|
||||
|
||||
virtual bool canExchange(const ChainActor * other) const;
|
||||
virtual std::string toString() const;
|
||||
ChainActor * exchange(const ChainActor * other) const { return exchange(this, other); }
|
||||
void setBaseActor(HeroActor * base);
|
||||
|
||||
@ -102,9 +103,13 @@ protected:
|
||||
|
||||
class DwellingActor : public ChainActor
|
||||
{
|
||||
private:
|
||||
const CGDwelling * dwelling;
|
||||
|
||||
public:
|
||||
DwellingActor(const CGDwelling * dwelling, uint64_t chainMask, bool waitForGrowth, int dayOfWeek);
|
||||
~DwellingActor();
|
||||
virtual std::string toString() const override;
|
||||
|
||||
protected:
|
||||
int getInitialTurn(bool waitForGrowth, int dayOfWeek);
|
||||
@ -113,6 +118,10 @@ protected:
|
||||
|
||||
class TownGarrisonActor : public ChainActor
|
||||
{
|
||||
private:
|
||||
const CGTownInstance * town;
|
||||
|
||||
public:
|
||||
TownGarrisonActor(const CGTownInstance * town, uint64_t chainMask);
|
||||
virtual std::string toString() const override;
|
||||
};
|
@ -35,13 +35,5 @@ namespace AIPathfinding
|
||||
#endif
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user