mirror of
https://github.com/vcmi/vcmi.git
synced 2025-08-13 19:54:17 +02:00
Code style: formatting and refactoring of VCAI code
This commit is contained in:
committed by
ArseniyShestakov
parent
2ede3783dd
commit
25dea1a599
@@ -23,7 +23,7 @@
|
||||
|
||||
extern boost::thread_specific_ptr<CCallback> cb;
|
||||
extern boost::thread_specific_ptr<VCAI> ai;
|
||||
extern FuzzyHelper *fh;
|
||||
extern FuzzyHelper * fh;
|
||||
|
||||
//extern static const int3 dirs[8];
|
||||
|
||||
@@ -32,27 +32,29 @@ const CGObjectInstance * ObjectIdRef::operator->() const
|
||||
return cb->getObj(id, false);
|
||||
}
|
||||
|
||||
ObjectIdRef::operator const CGObjectInstance*() const
|
||||
ObjectIdRef::operator const CGObjectInstance *() const
|
||||
{
|
||||
return cb->getObj(id, false);
|
||||
}
|
||||
|
||||
ObjectIdRef::ObjectIdRef(ObjectInstanceID _id) : id(_id)
|
||||
ObjectIdRef::ObjectIdRef(ObjectInstanceID _id)
|
||||
: id(_id)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
ObjectIdRef::ObjectIdRef(const CGObjectInstance *obj) : id(obj->id)
|
||||
ObjectIdRef::ObjectIdRef(const CGObjectInstance * obj)
|
||||
: id(obj->id)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bool ObjectIdRef::operator<(const ObjectIdRef &rhs) const
|
||||
bool ObjectIdRef::operator<(const ObjectIdRef & rhs) const
|
||||
{
|
||||
return id < rhs.id;
|
||||
}
|
||||
|
||||
HeroPtr::HeroPtr(const CGHeroInstance *H)
|
||||
HeroPtr::HeroPtr(const CGHeroInstance * H)
|
||||
{
|
||||
if(!H)
|
||||
{
|
||||
@@ -63,7 +65,6 @@ HeroPtr::HeroPtr(const CGHeroInstance *H)
|
||||
|
||||
h = H;
|
||||
name = h->name;
|
||||
|
||||
hid = H->id;
|
||||
// infosCount[ai->playerID][hid]++;
|
||||
}
|
||||
@@ -80,7 +81,7 @@ HeroPtr::~HeroPtr()
|
||||
// infosCount[ai->playerID][hid]--;
|
||||
}
|
||||
|
||||
bool HeroPtr::operator<(const HeroPtr &rhs) const
|
||||
bool HeroPtr::operator<(const HeroPtr & rhs) const
|
||||
{
|
||||
return hid < rhs.hid;
|
||||
}
|
||||
@@ -126,55 +127,59 @@ const CGHeroInstance * HeroPtr::operator*() const
|
||||
return get();
|
||||
}
|
||||
|
||||
void foreach_tile_pos(std::function<void(const int3& pos)> foo)
|
||||
void foreach_tile_pos(std::function<void(const int3 & pos)> foo)
|
||||
{
|
||||
// some micro-optimizations since this function gets called a LOT
|
||||
// callback pointer is thread-specific and slow to retrieve -> read map size only once
|
||||
int3 mapSize = cb->getMapSize();
|
||||
|
||||
for(int i = 0; i < mapSize.x; i++)
|
||||
{
|
||||
for(int j = 0; j < mapSize.y; j++)
|
||||
{
|
||||
for(int k = 0; k < mapSize.z; k++)
|
||||
foo(int3(i,j,k));
|
||||
|
||||
foo(int3(i, j, k));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void foreach_tile_pos(CCallback * cbp, std::function<void(CCallback * cbp, const int3& pos)> foo)
|
||||
void foreach_tile_pos(CCallback * cbp, std::function<void(CCallback * cbp, const int3 & pos)> foo)
|
||||
{
|
||||
int3 mapSize = cbp->getMapSize();
|
||||
|
||||
for(int i = 0; i < mapSize.x; i++)
|
||||
{
|
||||
for(int j = 0; j < mapSize.y; j++)
|
||||
{
|
||||
for(int k = 0; k < mapSize.z; k++)
|
||||
foo(cbp, int3(i,j,k));
|
||||
foo(cbp, int3(i, j, k));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void foreach_neighbour(const int3 &pos, std::function<void(const int3& pos)> foo)
|
||||
void foreach_neighbour(const int3 & pos, std::function<void(const int3 & pos)> foo)
|
||||
{
|
||||
CCallback * cbp = cb.get(); // avoid costly retrieval of thread-specific pointer
|
||||
|
||||
for(const int3 &dir : int3::getDirs())
|
||||
for(const int3 & dir : int3::getDirs())
|
||||
{
|
||||
const int3 n = pos + dir;
|
||||
if(cbp->isInTheMap(n))
|
||||
foo(pos+dir);
|
||||
foo(pos + dir);
|
||||
}
|
||||
}
|
||||
|
||||
void foreach_neighbour(CCallback * cbp, const int3 &pos, std::function<void(CCallback * cbp, const int3& pos)> foo)
|
||||
void foreach_neighbour(CCallback * cbp, const int3 & pos, std::function<void(CCallback * cbp, const int3 & pos)> foo)
|
||||
{
|
||||
for(const int3 &dir : int3::getDirs())
|
||||
for(const int3 & dir : int3::getDirs())
|
||||
{
|
||||
const int3 n = pos + dir;
|
||||
if(cbp->isInTheMap(n))
|
||||
foo(cbp, pos+dir);
|
||||
foo(cbp, pos + dir);
|
||||
}
|
||||
}
|
||||
|
||||
bool CDistanceSorter::operator ()(const CGObjectInstance *lhs, const CGObjectInstance *rhs)
|
||||
bool CDistanceSorter::operator()(const CGObjectInstance * lhs, const CGObjectInstance * rhs)
|
||||
{
|
||||
const CGPathNode *ln = ai->myCb->getPathsInfo(hero)->getPathInfo(lhs->visitablePos()),
|
||||
*rn = ai->myCb->getPathsInfo(hero)->getPathInfo(rhs->visitablePos());
|
||||
const CGPathNode * ln = ai->myCb->getPathsInfo(hero)->getPathInfo(lhs->visitablePos());
|
||||
const CGPathNode * rn = ai->myCb->getPathsInfo(hero)->getPathInfo(rhs->visitablePos());
|
||||
|
||||
if(ln->turns != rn->turns)
|
||||
return ln->turns < rn->turns;
|
||||
@@ -189,11 +194,12 @@ bool compareMovement(HeroPtr lhs, HeroPtr rhs)
|
||||
|
||||
ui64 evaluateDanger(crint3 tile)
|
||||
{
|
||||
const TerrainTile *t = cb->getTile(tile, false);
|
||||
const TerrainTile * t = cb->getTile(tile, false);
|
||||
if(!t) //we can know about guard but can't check its tile (the edge of fow)
|
||||
return 190000000; //MUCH
|
||||
|
||||
ui64 objectDanger = 0, guardDanger = 0;
|
||||
ui64 objectDanger = 0;
|
||||
ui64 guardDanger = 0;
|
||||
|
||||
auto visObjs = cb->getVisitableObjs(tile);
|
||||
if(visObjs.size())
|
||||
@@ -207,62 +213,64 @@ ui64 evaluateDanger(crint3 tile)
|
||||
return std::max(objectDanger, guardDanger);
|
||||
}
|
||||
|
||||
ui64 evaluateDanger(crint3 tile, const CGHeroInstance *visitor)
|
||||
ui64 evaluateDanger(crint3 tile, const CGHeroInstance * visitor)
|
||||
{
|
||||
const TerrainTile *t = cb->getTile(tile, false);
|
||||
const TerrainTile * t = cb->getTile(tile, false);
|
||||
if(!t) //we can know about guard but can't check its tile (the edge of fow)
|
||||
return 190000000; //MUCH
|
||||
|
||||
ui64 objectDanger = 0, guardDanger = 0;
|
||||
ui64 objectDanger = 0;
|
||||
ui64 guardDanger = 0;
|
||||
|
||||
auto visitableObjects = cb->getVisitableObjs(tile);
|
||||
// in some scenarios hero happens to be "under" the object (eg town). Then we consider ONLY the hero.
|
||||
if(vstd::contains_if(visitableObjects, objWithID<Obj::HERO>))
|
||||
{
|
||||
vstd::erase_if(visitableObjects, [](const CGObjectInstance * obj)
|
||||
{
|
||||
return !objWithID<Obj::HERO>(obj);
|
||||
});
|
||||
}
|
||||
|
||||
if(const CGObjectInstance * dangerousObject = vstd::backOrNull(visitableObjects))
|
||||
{
|
||||
objectDanger = evaluateDanger(dangerousObject); //unguarded objects can also be dangerous or unhandled
|
||||
if (objectDanger)
|
||||
if(objectDanger)
|
||||
{
|
||||
//TODO: don't downcast objects AI shouldn't know about!
|
||||
auto armedObj = dynamic_cast<const CArmedInstance*>(dangerousObject);
|
||||
if (armedObj)
|
||||
auto armedObj = dynamic_cast<const CArmedInstance *>(dangerousObject);
|
||||
if(armedObj)
|
||||
{
|
||||
float tacticalAdvantage = fh->getTacticalAdvantage(visitor, armedObj);
|
||||
objectDanger *= tacticalAdvantage; //this line tends to go infinite for allied towns (?)
|
||||
}
|
||||
}
|
||||
if (dangerousObject->ID == Obj::SUBTERRANEAN_GATE)
|
||||
{ //check guard on the other side of the gate
|
||||
if(dangerousObject->ID == Obj::SUBTERRANEAN_GATE)
|
||||
{
|
||||
//check guard on the other side of the gate
|
||||
auto it = ai->knownSubterraneanGates.find(dangerousObject);
|
||||
if (it != ai->knownSubterraneanGates.end())
|
||||
if(it != ai->knownSubterraneanGates.end())
|
||||
{
|
||||
auto guards = cb->getGuardingCreatures(it->second->visitablePos());
|
||||
for (auto cre : guards)
|
||||
for(auto cre : guards)
|
||||
{
|
||||
vstd::amax (guardDanger, evaluateDanger(cre) *
|
||||
fh->getTacticalAdvantage(visitor, dynamic_cast<const CArmedInstance*>(cre)));
|
||||
vstd::amax(guardDanger, evaluateDanger(cre) * fh->getTacticalAdvantage(visitor, dynamic_cast<const CArmedInstance *>(cre)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
auto guards = cb->getGuardingCreatures(tile);
|
||||
for (auto cre : guards)
|
||||
for(auto cre : guards)
|
||||
{
|
||||
vstd::amax (guardDanger, evaluateDanger(cre) * fh->getTacticalAdvantage(visitor, dynamic_cast<const CArmedInstance*>(cre))); //we are interested in strongest monster around
|
||||
vstd::amax(guardDanger, evaluateDanger(cre) * fh->getTacticalAdvantage(visitor, dynamic_cast<const CArmedInstance *>(cre))); //we are interested in strongest monster around
|
||||
}
|
||||
|
||||
|
||||
//TODO mozna odwiedzic blockvis nie ruszajac straznika
|
||||
return std::max(objectDanger, guardDanger);
|
||||
}
|
||||
|
||||
ui64 evaluateDanger(const CGObjectInstance *obj)
|
||||
ui64 evaluateDanger(const CGObjectInstance * obj)
|
||||
{
|
||||
if(obj->tempOwner < PlayerColor::PLAYER_LIMIT && cb->getPlayerRelations(obj->tempOwner, ai->playerID) != PlayerRelations::ENEMIES) //owned or allied objects don't pose any threat
|
||||
return 0;
|
||||
@@ -276,7 +284,8 @@ ui64 evaluateDanger(const CGObjectInstance *obj)
|
||||
return iah.army.getStrength();
|
||||
}
|
||||
case Obj::TOWN:
|
||||
case Obj::GARRISON: case Obj::GARRISON2: //garrison
|
||||
case Obj::GARRISON:
|
||||
case Obj::GARRISON2:
|
||||
{
|
||||
InfoAboutTown iat;
|
||||
cb->getTownInfo(obj, iat);
|
||||
@@ -285,19 +294,19 @@ ui64 evaluateDanger(const CGObjectInstance *obj)
|
||||
case Obj::MONSTER:
|
||||
{
|
||||
//TODO!!!!!!!!
|
||||
const CGCreature *cre = dynamic_cast<const CGCreature*>(obj);
|
||||
const CGCreature * cre = dynamic_cast<const CGCreature *>(obj);
|
||||
return cre->getArmyStrength();
|
||||
}
|
||||
case Obj::CREATURE_GENERATOR1:
|
||||
case Obj::CREATURE_GENERATOR4:
|
||||
{
|
||||
const CGDwelling *d = dynamic_cast<const CGDwelling*>(obj);
|
||||
const CGDwelling * d = dynamic_cast<const CGDwelling *>(obj);
|
||||
return d->getArmyStrength();
|
||||
}
|
||||
case Obj::MINE:
|
||||
case Obj::ABANDONED_MINE:
|
||||
{
|
||||
const CArmedInstance * a = dynamic_cast<const CArmedInstance*>(obj);
|
||||
const CArmedInstance * a = dynamic_cast<const CArmedInstance *>(obj);
|
||||
return a->getArmyStrength();
|
||||
}
|
||||
case Obj::CRYPT: //crypt
|
||||
@@ -306,11 +315,11 @@ ui64 evaluateDanger(const CGObjectInstance *obj)
|
||||
case Obj::SHIPWRECK: //shipwreck
|
||||
case Obj::DERELICT_SHIP: //derelict ship
|
||||
// case Obj::PYRAMID:
|
||||
return fh->estimateBankDanger (dynamic_cast<const CBank *>(obj));
|
||||
return fh->estimateBankDanger(dynamic_cast<const CBank *>(obj));
|
||||
case Obj::PYRAMID:
|
||||
{
|
||||
if(obj->subID == 0)
|
||||
return fh->estimateBankDanger (dynamic_cast<const CBank *>(obj));
|
||||
return fh->estimateBankDanger(dynamic_cast<const CBank *>(obj));
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
@@ -319,15 +328,15 @@ ui64 evaluateDanger(const CGObjectInstance *obj)
|
||||
}
|
||||
}
|
||||
|
||||
bool compareDanger(const CGObjectInstance *lhs, const CGObjectInstance *rhs)
|
||||
bool compareDanger(const CGObjectInstance * lhs, const CGObjectInstance * rhs)
|
||||
{
|
||||
return evaluateDanger(lhs) < evaluateDanger(rhs);
|
||||
}
|
||||
|
||||
bool isSafeToVisit(HeroPtr h, crint3 tile)
|
||||
{
|
||||
const ui64 heroStrength = h->getTotalStrength(),
|
||||
dangerStrength = evaluateDanger(tile, *h);
|
||||
const ui64 heroStrength = h->getTotalStrength();
|
||||
const ui64 dangerStrength = evaluateDanger(tile, *h);
|
||||
if(dangerStrength)
|
||||
{
|
||||
if(heroStrength / SAFE_ATTACK_CONSTANT > dangerStrength)
|
||||
@@ -336,23 +345,33 @@ bool isSafeToVisit(HeroPtr h, crint3 tile)
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true; //there's no danger
|
||||
}
|
||||
|
||||
bool canBeEmbarkmentPoint(const TerrainTile *t, bool fromWater)
|
||||
bool canBeEmbarkmentPoint(const TerrainTile * t, bool fromWater)
|
||||
{
|
||||
//tile must be free of with unoccupied boat
|
||||
return !t->blocked
|
||||
|| (!fromWater && t->visitableObjects.size() == 1 && t->topVisitableId() == Obj::BOAT);
|
||||
//do not try to board when in water sector
|
||||
// TODO: Such information should be provided by pathfinder
|
||||
// Tile must be free or with unoccupied boat
|
||||
if(!t->blocked)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else if(!fromWater) // do not try to board when in water sector
|
||||
{
|
||||
if(t->visitableObjects.size() == 1 && t->topVisitableId() == Obj::BOAT)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
int3 whereToExplore(HeroPtr h)
|
||||
{
|
||||
TimeCheck tc ("where to explore");
|
||||
TimeCheck tc("where to explore");
|
||||
int radius = h->getSightRadius();
|
||||
int3 hpos = h->visitablePos();
|
||||
|
||||
@@ -361,22 +380,24 @@ int3 whereToExplore(HeroPtr h)
|
||||
//look for nearby objs -> visit them if they're close enouh
|
||||
const int DIST_LIMIT = 3;
|
||||
std::vector<const CGObjectInstance *> nearbyVisitableObjs;
|
||||
for (int x = hpos.x - DIST_LIMIT; x <= hpos.x + DIST_LIMIT; ++x) //get only local objects instead of all possible objects on the map
|
||||
for(int x = hpos.x - DIST_LIMIT; x <= hpos.x + DIST_LIMIT; ++x) //get only local objects instead of all possible objects on the map
|
||||
{
|
||||
for (int y = hpos.y - DIST_LIMIT; y <= hpos.y + DIST_LIMIT; ++y)
|
||||
for(int y = hpos.y - DIST_LIMIT; y <= hpos.y + DIST_LIMIT; ++y)
|
||||
{
|
||||
for (auto obj : cb->getVisitableObjs (int3(x,y,hpos.z), false))
|
||||
for(auto obj : cb->getVisitableObjs(int3(x, y, hpos.z), false))
|
||||
{
|
||||
int3 op = obj->visitablePos();
|
||||
CGPath p;
|
||||
ai->myCb->getPathsInfo(h.get())->getPath(p, op);
|
||||
if (p.nodes.size() && p.endPos() == op && p.nodes.size() <= DIST_LIMIT)
|
||||
if (ai->isGoodForVisit(obj, h, *sm))
|
||||
if(p.nodes.size() && p.endPos() == op && p.nodes.size() <= DIST_LIMIT)
|
||||
{
|
||||
if(ai->isGoodForVisit(obj, h, *sm))
|
||||
nearbyVisitableObjs.push_back(obj);
|
||||
}
|
||||
}
|
||||
}
|
||||
vstd::removeDuplicates (nearbyVisitableObjs); //one object may occupy multiple tiles
|
||||
}
|
||||
vstd::removeDuplicates(nearbyVisitableObjs); //one object may occupy multiple tiles
|
||||
boost::sort(nearbyVisitableObjs, CDistanceSorter(h.get()));
|
||||
if(nearbyVisitableObjs.size())
|
||||
return nearbyVisitableObjs.back()->visitablePos();
|
||||
@@ -385,7 +406,7 @@ int3 whereToExplore(HeroPtr h)
|
||||
{
|
||||
return ai->explorationBestNeighbour(hpos, radius, h);
|
||||
}
|
||||
catch(cannotFulfillGoalException &e)
|
||||
catch(cannotFulfillGoalException & e)
|
||||
{
|
||||
//perform exhaustive search
|
||||
return ai->explorationNewPoint(h);
|
||||
@@ -394,29 +415,34 @@ int3 whereToExplore(HeroPtr h)
|
||||
|
||||
bool isBlockedBorderGate(int3 tileToHit) //TODO: is that function needed? should be handled by pathfinder
|
||||
{
|
||||
return cb->getTile(tileToHit)->topVisitableId() == Obj::BORDER_GATE &&
|
||||
(dynamic_cast <const CGKeys *>(cb->getTile(tileToHit)->visitableObjects.back()))->wasMyColorVisited (ai->playerID);
|
||||
if(cb->getTile(tileToHit)->topVisitableId() != Obj::BORDER_GATE)
|
||||
return false;
|
||||
auto gate = dynamic_cast<const CGKeys *>(cb->getTile(tileToHit)->topVisitableObj());
|
||||
return !gate->wasMyColorVisited(ai->playerID);
|
||||
}
|
||||
bool isBlockVisitObj(const int3 &pos)
|
||||
bool isBlockVisitObj(const int3 & pos)
|
||||
{
|
||||
if (auto obj = cb->getTopObj(pos))
|
||||
if (obj->blockVisit) //we can't stand on that object
|
||||
if(auto obj = cb->getTopObj(pos))
|
||||
{
|
||||
if(obj->blockVisit) //we can't stand on that object
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
int howManyTilesWillBeDiscovered(const int3 &pos, int radious, CCallback * cbp)
|
||||
{ //TODO: do not explore dead-end boundaries
|
||||
int howManyTilesWillBeDiscovered(const int3 & pos, int radious, CCallback * cbp)
|
||||
{
|
||||
//TODO: do not explore dead-end boundaries
|
||||
int ret = 0;
|
||||
for(int x = pos.x - radious; x <= pos.x + radious; x++)
|
||||
{
|
||||
for(int y = pos.y - radious; y <= pos.y + radious; y++)
|
||||
{
|
||||
int3 npos = int3(x,y,pos.z);
|
||||
int3 npos = int3(x, y, pos.z);
|
||||
if(cbp->isInTheMap(npos) && pos.dist2d(npos) - 0.5 < radious && !cbp->isVisible(npos))
|
||||
{
|
||||
if (!boundaryBetweenTwoPoints (pos, npos, cbp))
|
||||
if(!boundaryBetweenTwoPoints(pos, npos, cbp))
|
||||
ret++;
|
||||
}
|
||||
}
|
||||
@@ -425,21 +451,21 @@ int howManyTilesWillBeDiscovered(const int3 &pos, int radious, CCallback * cbp)
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool boundaryBetweenTwoPoints (int3 pos1, int3 pos2, CCallback * cbp) //determines if two points are separated by known barrier
|
||||
bool boundaryBetweenTwoPoints(int3 pos1, int3 pos2, CCallback * cbp) //determines if two points are separated by known barrier
|
||||
{
|
||||
int xMin = std::min (pos1.x, pos2.x);
|
||||
int xMax = std::max (pos1.x, pos2.x);
|
||||
int yMin = std::min (pos1.y, pos2.y);
|
||||
int yMax = std::max (pos1.y, pos2.y);
|
||||
int xMin = std::min(pos1.x, pos2.x);
|
||||
int xMax = std::max(pos1.x, pos2.x);
|
||||
int yMin = std::min(pos1.y, pos2.y);
|
||||
int yMax = std::max(pos1.y, pos2.y);
|
||||
|
||||
for (int x = xMin; x <= xMax; ++x)
|
||||
for(int x = xMin; x <= xMax; ++x)
|
||||
{
|
||||
for (int y = yMin; y <= yMax; ++y)
|
||||
for(int y = yMin; y <= yMax; ++y)
|
||||
{
|
||||
int3 tile = int3(x, y, pos1.z); //use only on same level, ofc
|
||||
if (std::abs(pos1.dist2d(tile) - pos2.dist2d(tile)) < 1.5)
|
||||
if(std::abs(pos1.dist2d(tile) - pos2.dist2d(tile)) < 1.5)
|
||||
{
|
||||
if (!(cbp->isVisible(tile) && cbp->getTile(tile)->blocked)) //if there's invisible or unblocked tile between, it's good
|
||||
if(!(cbp->isVisible(tile) && cbp->getTile(tile)->blocked)) //if there's invisible or unblocked tile between, it's good
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -452,9 +478,9 @@ int howManyTilesWillBeDiscovered(int radious, int3 pos, crint3 dir)
|
||||
return howManyTilesWillBeDiscovered(pos + dir, radious, cb.get());
|
||||
}
|
||||
|
||||
void getVisibleNeighbours(const std::vector<int3> &tiles, std::vector<int3> &out)
|
||||
void getVisibleNeighbours(const std::vector<int3> & tiles, std::vector<int3> & out)
|
||||
{
|
||||
for(const int3 &tile : tiles)
|
||||
for(const int3 & tile : tiles)
|
||||
{
|
||||
foreach_neighbour(tile, [&](int3 neighbour)
|
||||
{
|
||||
@@ -464,7 +490,7 @@ void getVisibleNeighbours(const std::vector<int3> &tiles, std::vector<int3> &out
|
||||
}
|
||||
}
|
||||
|
||||
ui64 howManyReinforcementsCanGet(HeroPtr h, const CGTownInstance *t)
|
||||
ui64 howManyReinforcementsCanGet(HeroPtr h, const CGTownInstance * t)
|
||||
{
|
||||
ui64 ret = 0;
|
||||
int freeHeroSlots = GameConstants::ARMY_SIZE - h->stacksCount();
|
||||
@@ -478,11 +504,11 @@ ui64 howManyReinforcementsCanGet(HeroPtr h, const CGTownInstance *t)
|
||||
else
|
||||
toMove.push_back(slot.second);
|
||||
}
|
||||
boost::sort(toMove, [](const CStackInstance *lhs, const CStackInstance *rhs)
|
||||
boost::sort(toMove, [](const CStackInstance * lhs, const CStackInstance * rhs)
|
||||
{
|
||||
return lhs->getPower() < rhs->getPower();
|
||||
});
|
||||
for (auto & stack : boost::adaptors::reverse(toMove))
|
||||
for(auto & stack : boost::adaptors::reverse(toMove))
|
||||
{
|
||||
if(freeHeroSlots)
|
||||
{
|
||||
@@ -500,12 +526,12 @@ bool compareHeroStrength(HeroPtr h1, HeroPtr h2)
|
||||
return h1->getTotalStrength() < h2->getTotalStrength();
|
||||
}
|
||||
|
||||
bool compareArmyStrength(const CArmedInstance *a1, const CArmedInstance *a2)
|
||||
bool compareArmyStrength(const CArmedInstance * a1, const CArmedInstance * a2)
|
||||
{
|
||||
return a1->getArmyStrength() < a2->getArmyStrength();
|
||||
}
|
||||
|
||||
bool compareArtifacts(const CArtifactInstance *a1, const CArtifactInstance *a2)
|
||||
bool compareArtifacts(const CArtifactInstance * a1, const CArtifactInstance * a2)
|
||||
{
|
||||
auto art1 = a1->artType;
|
||||
auto art2 = a2->artType;
|
||||
|
@@ -20,8 +20,8 @@
|
||||
|
||||
class CCallback;
|
||||
|
||||
typedef const int3& crint3;
|
||||
typedef const std::string& crstring;
|
||||
typedef const int3 & crint3;
|
||||
typedef const std::string & crstring;
|
||||
|
||||
const int GOLD_MINE_PRODUCTION = 1000, WOOD_ORE_MINE_PRODUCTION = 2, RESOURCE_MINE_PRODUCTION = 1;
|
||||
const int ACTUAL_RESOURCE_COUNT = 7;
|
||||
@@ -36,7 +36,7 @@ extern const int GOLD_RESERVE;
|
||||
|
||||
struct HeroPtr
|
||||
{
|
||||
const CGHeroInstance *h;
|
||||
const CGHeroInstance * h;
|
||||
ObjectInstanceID hid;
|
||||
|
||||
public:
|
||||
@@ -44,7 +44,7 @@ public:
|
||||
|
||||
|
||||
HeroPtr();
|
||||
HeroPtr(const CGHeroInstance *H);
|
||||
HeroPtr(const CGHeroInstance * H);
|
||||
~HeroPtr();
|
||||
|
||||
operator bool() const
|
||||
@@ -52,15 +52,15 @@ public:
|
||||
return validAndSet();
|
||||
}
|
||||
|
||||
bool operator<(const HeroPtr &rhs) const;
|
||||
const CGHeroInstance *operator->() const;
|
||||
const CGHeroInstance *operator*() const; //not that consistent with -> but all interfaces use CGHeroInstance*, so it's convenient
|
||||
bool operator<(const HeroPtr & rhs) const;
|
||||
const CGHeroInstance * operator->() const;
|
||||
const CGHeroInstance * operator*() const; //not that consistent with -> but all interfaces use CGHeroInstance*, so it's convenient
|
||||
|
||||
const CGHeroInstance *get(bool doWeExpectNull = false) const;
|
||||
const CGHeroInstance * get(bool doWeExpectNull = false) const;
|
||||
bool validAndSet() const;
|
||||
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
template<typename Handler> void serialize(Handler & h, const int version)
|
||||
{
|
||||
h & this->h;
|
||||
h & hid;
|
||||
@@ -82,16 +82,16 @@ struct ObjectIdRef
|
||||
{
|
||||
ObjectInstanceID id;
|
||||
|
||||
const CGObjectInstance *operator->() const;
|
||||
const CGObjectInstance * operator->() const;
|
||||
operator const CGObjectInstance *() const;
|
||||
|
||||
ObjectIdRef(ObjectInstanceID _id);
|
||||
ObjectIdRef(const CGObjectInstance *obj);
|
||||
ObjectIdRef(const CGObjectInstance * obj);
|
||||
|
||||
bool operator<(const ObjectIdRef &rhs) const;
|
||||
bool operator<(const ObjectIdRef & rhs) const;
|
||||
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
template<typename Handler> void serialize(Handler & h, const int version)
|
||||
{
|
||||
h & id;
|
||||
}
|
||||
@@ -101,13 +101,14 @@ struct TimeCheck
|
||||
{
|
||||
CStopWatch time;
|
||||
std::string txt;
|
||||
TimeCheck(crstring TXT) : txt(TXT)
|
||||
TimeCheck(crstring TXT)
|
||||
: txt(TXT)
|
||||
{
|
||||
}
|
||||
|
||||
~TimeCheck()
|
||||
{
|
||||
logAi->trace("Time of %s was %d ms.",txt,time.getDiff());
|
||||
logAi->trace("Time of %s was %d ms.", txt, time.getDiff());
|
||||
}
|
||||
};
|
||||
|
||||
@@ -115,7 +116,8 @@ struct TimeCheck
|
||||
struct AtScopeExit
|
||||
{
|
||||
std::function<void()> foo;
|
||||
AtScopeExit(const std::function<void()> &FOO) : foo(FOO)
|
||||
AtScopeExit(const std::function<void()> & FOO)
|
||||
: foo(FOO)
|
||||
{}
|
||||
~AtScopeExit()
|
||||
{
|
||||
@@ -126,48 +128,50 @@ struct AtScopeExit
|
||||
|
||||
class ObjsVector : public std::vector<ObjectIdRef>
|
||||
{
|
||||
private:
|
||||
};
|
||||
|
||||
template<int id>
|
||||
bool objWithID(const CGObjectInstance *obj)
|
||||
bool objWithID(const CGObjectInstance * obj)
|
||||
{
|
||||
return obj->ID == id;
|
||||
}
|
||||
|
||||
void foreach_tile_pos(std::function<void(const int3& pos)> foo);
|
||||
void foreach_tile_pos(CCallback * cbp, std::function<void(CCallback * cbp, const int3& pos)> foo); // avoid costly retrieval of thread-specific pointer
|
||||
void foreach_neighbour(const int3 &pos, std::function<void(const int3& pos)> foo);
|
||||
void foreach_neighbour(CCallback * cbp, const int3 &pos, std::function<void(CCallback * cbp, const int3& pos)> foo); // avoid costly retrieval of thread-specific pointer
|
||||
void foreach_tile_pos(std::function<void(const int3 & pos)> foo);
|
||||
void foreach_tile_pos(CCallback * cbp, std::function<void(CCallback * cbp, const int3 & pos)> foo); // avoid costly retrieval of thread-specific pointer
|
||||
void foreach_neighbour(const int3 & pos, std::function<void(const int3 & pos)> foo);
|
||||
void foreach_neighbour(CCallback * cbp, const int3 & pos, std::function<void(CCallback * cbp, const int3 & pos)> foo); // avoid costly retrieval of thread-specific pointer
|
||||
|
||||
int howManyTilesWillBeDiscovered(const int3 &pos, int radious, CCallback * cbp);
|
||||
int howManyTilesWillBeDiscovered(const int3 & pos, int radious, CCallback * cbp);
|
||||
int howManyTilesWillBeDiscovered(int radious, int3 pos, crint3 dir);
|
||||
void getVisibleNeighbours(const std::vector<int3> &tiles, std::vector<int3> &out);
|
||||
void getVisibleNeighbours(const std::vector<int3> & tiles, std::vector<int3> & out);
|
||||
|
||||
bool canBeEmbarkmentPoint(const TerrainTile *t, bool fromWater);
|
||||
bool canBeEmbarkmentPoint(const TerrainTile * t, bool fromWater);
|
||||
bool isBlockedBorderGate(int3 tileToHit);
|
||||
bool isBlockVisitObj(const int3 &pos);
|
||||
bool isBlockVisitObj(const int3 & pos);
|
||||
|
||||
bool isWeeklyRevisitable (const CGObjectInstance * obj);
|
||||
bool shouldVisit (HeroPtr h, const CGObjectInstance * obj);
|
||||
bool isWeeklyRevisitable(const CGObjectInstance * obj);
|
||||
bool shouldVisit(HeroPtr h, const CGObjectInstance * obj);
|
||||
|
||||
ui64 evaluateDanger(const CGObjectInstance *obj);
|
||||
ui64 evaluateDanger(crint3 tile, const CGHeroInstance *visitor);
|
||||
ui64 evaluateDanger(const CGObjectInstance * obj);
|
||||
ui64 evaluateDanger(crint3 tile, const CGHeroInstance * visitor);
|
||||
bool isSafeToVisit(HeroPtr h, crint3 tile);
|
||||
bool boundaryBetweenTwoPoints (int3 pos1, int3 pos2, CCallback * cbp);
|
||||
bool boundaryBetweenTwoPoints(int3 pos1, int3 pos2, CCallback * cbp);
|
||||
|
||||
bool compareMovement(HeroPtr lhs, HeroPtr rhs);
|
||||
bool compareHeroStrength(HeroPtr h1, HeroPtr h2);
|
||||
bool compareArmyStrength(const CArmedInstance *a1, const CArmedInstance *a2);
|
||||
bool compareArtifacts(const CArtifactInstance *a1, const CArtifactInstance *a2);
|
||||
ui64 howManyReinforcementsCanGet(HeroPtr h, const CGTownInstance *t);
|
||||
bool compareArmyStrength(const CArmedInstance * a1, const CArmedInstance * a2);
|
||||
bool compareArtifacts(const CArtifactInstance * a1, const CArtifactInstance * a2);
|
||||
ui64 howManyReinforcementsCanGet(HeroPtr h, const CGTownInstance * t);
|
||||
int3 whereToExplore(HeroPtr h);
|
||||
|
||||
class CDistanceSorter
|
||||
{
|
||||
const CGHeroInstance * hero;
|
||||
public:
|
||||
CDistanceSorter(const CGHeroInstance * hero): hero(hero) {}
|
||||
|
||||
bool operator ()(const CGObjectInstance *lhs, const CGObjectInstance *rhs);
|
||||
public:
|
||||
CDistanceSorter(const CGHeroInstance * hero)
|
||||
: hero(hero)
|
||||
{
|
||||
}
|
||||
bool operator()(const CGObjectInstance * lhs, const CGObjectInstance * rhs);
|
||||
};
|
||||
|
@@ -29,9 +29,7 @@ class Engine;
|
||||
class InputVariable;
|
||||
class CGTownInstance;
|
||||
|
||||
//using namespace Goals;
|
||||
|
||||
FuzzyHelper *fh;
|
||||
FuzzyHelper * fh;
|
||||
|
||||
extern boost::thread_specific_ptr<CCallback> cb;
|
||||
extern boost::thread_specific_ptr<VCAI> ai;
|
||||
@@ -47,7 +45,7 @@ void engineBase::configure()
|
||||
logAi->info(engine.toString());
|
||||
}
|
||||
|
||||
void engineBase::addRule(const std::string &txt)
|
||||
void engineBase::addRule(const std::string & txt)
|
||||
{
|
||||
rules.addRule(fl::Rule::parse(txt, &engine));
|
||||
}
|
||||
@@ -58,7 +56,7 @@ struct armyStructure
|
||||
ui32 maxSpeed;
|
||||
};
|
||||
|
||||
armyStructure evaluateArmyStructure (const CArmedInstance * army)
|
||||
armyStructure evaluateArmyStructure(const CArmedInstance * army)
|
||||
{
|
||||
ui64 totalStrenght = army->getArmyStrength();
|
||||
double walkersStrenght = 0;
|
||||
@@ -69,17 +67,17 @@ armyStructure evaluateArmyStructure (const CArmedInstance * army)
|
||||
for(auto s : army->Slots())
|
||||
{
|
||||
bool walker = true;
|
||||
if (s.second->type->hasBonusOfType(Bonus::SHOOTER))
|
||||
if(s.second->type->hasBonusOfType(Bonus::SHOOTER))
|
||||
{
|
||||
shootersStrenght += s.second->getPower();
|
||||
walker = false;
|
||||
}
|
||||
if (s.second->type->hasBonusOfType(Bonus::FLYING))
|
||||
if(s.second->type->hasBonusOfType(Bonus::FLYING))
|
||||
{
|
||||
flyersStrenght += s.second->getPower();
|
||||
walker = false;
|
||||
}
|
||||
if (walker)
|
||||
if(walker)
|
||||
walkersStrenght += s.second->getPower();
|
||||
|
||||
vstd::amax(maxSpeed, s.second->type->valOfBonuses(Bonus::STACKS_SPEED));
|
||||
@@ -106,7 +104,6 @@ void FuzzyHelper::initTacticalAdvantage()
|
||||
{
|
||||
try
|
||||
{
|
||||
|
||||
ta.ourShooters = new fl::InputVariable("OurShooters");
|
||||
ta.ourWalkers = new fl::InputVariable("OurWalkers");
|
||||
ta.ourFlyers = new fl::InputVariable("OurFlyers");
|
||||
@@ -115,12 +112,12 @@ void FuzzyHelper::initTacticalAdvantage()
|
||||
ta.enemyFlyers = new fl::InputVariable("EnemyFlyers");
|
||||
|
||||
//Tactical advantage calculation
|
||||
std::vector<fl::InputVariable*> helper =
|
||||
std::vector<fl::InputVariable *> helper =
|
||||
{
|
||||
ta.ourShooters, ta.ourWalkers, ta.ourFlyers, ta.enemyShooters, ta.enemyWalkers, ta.enemyFlyers
|
||||
};
|
||||
|
||||
for (auto val : helper)
|
||||
for(auto val : helper)
|
||||
{
|
||||
ta.engine.addInputVariable(val);
|
||||
val->addTerm(new fl::Ramp("FEW", 0.6, 0.0));
|
||||
@@ -133,7 +130,7 @@ void FuzzyHelper::initTacticalAdvantage()
|
||||
|
||||
helper = {ta.ourSpeed, ta.enemySpeed};
|
||||
|
||||
for (auto val : helper)
|
||||
for(auto val : helper)
|
||||
{
|
||||
ta.engine.addInputVariable(val);
|
||||
val->addTerm(new fl::Ramp("LOW", 6.5, 3));
|
||||
@@ -145,27 +142,26 @@ void FuzzyHelper::initTacticalAdvantage()
|
||||
ta.castleWalls = new fl::InputVariable("CastleWalls");
|
||||
ta.engine.addInputVariable(ta.castleWalls);
|
||||
{
|
||||
fl::Rectangle* none = new fl::Rectangle("NONE", CGTownInstance::NONE, CGTownInstance::NONE + (CGTownInstance::FORT - CGTownInstance::NONE) * 0.5f);
|
||||
fl::Rectangle * none = new fl::Rectangle("NONE", CGTownInstance::NONE, CGTownInstance::NONE + (CGTownInstance::FORT - CGTownInstance::NONE) * 0.5f);
|
||||
ta.castleWalls->addTerm(none);
|
||||
|
||||
fl::Trapezoid* medium = new fl::Trapezoid("MEDIUM", (CGTownInstance::FORT - CGTownInstance::NONE) * 0.5f, CGTownInstance::FORT,
|
||||
fl::Trapezoid * medium = new fl::Trapezoid("MEDIUM", (CGTownInstance::FORT - CGTownInstance::NONE) * 0.5f, CGTownInstance::FORT,
|
||||
CGTownInstance::CITADEL, CGTownInstance::CITADEL + (CGTownInstance::CASTLE - CGTownInstance::CITADEL) * 0.5f);
|
||||
ta.castleWalls->addTerm(medium);
|
||||
|
||||
fl::Ramp* high = new fl::Ramp("HIGH", CGTownInstance::CITADEL - 0.1, CGTownInstance::CASTLE);
|
||||
fl::Ramp * high = new fl::Ramp("HIGH", CGTownInstance::CITADEL - 0.1, CGTownInstance::CASTLE);
|
||||
ta.castleWalls->addTerm(high);
|
||||
|
||||
ta.castleWalls->setRange(CGTownInstance::NONE, CGTownInstance::CASTLE);
|
||||
}
|
||||
|
||||
|
||||
|
||||
ta.bankPresent = new fl::InputVariable("Bank");
|
||||
ta.engine.addInputVariable(ta.bankPresent);
|
||||
{
|
||||
fl::Rectangle* termFalse = new fl::Rectangle("FALSE", 0.0, 0.5f);
|
||||
fl::Rectangle * termFalse = new fl::Rectangle("FALSE", 0.0, 0.5f);
|
||||
ta.bankPresent->addTerm(termFalse);
|
||||
fl::Rectangle* termTrue = new fl::Rectangle("TRUE", 0.5f, 1);
|
||||
fl::Rectangle * termTrue = new fl::Rectangle("TRUE", 0.5f, 1);
|
||||
ta.bankPresent->addTerm(termTrue);
|
||||
ta.bankPresent->setRange(0, 1);
|
||||
}
|
||||
@@ -197,23 +193,23 @@ void FuzzyHelper::initTacticalAdvantage()
|
||||
ta.addRule("if CastleWalls is MEDIUM and OurShooters is MANY and EnemyWalkers is MANY then Threat is LOW");
|
||||
|
||||
}
|
||||
catch (fl::Exception & pe)
|
||||
catch(fl::Exception & pe)
|
||||
{
|
||||
logAi->error("initTacticalAdvantage: %s", pe.getWhat());
|
||||
}
|
||||
}
|
||||
|
||||
ui64 FuzzyHelper::estimateBankDanger (const CBank * bank)
|
||||
ui64 FuzzyHelper::estimateBankDanger(const CBank * bank)
|
||||
{
|
||||
//this one is not fuzzy anymore, just calculate weighted average
|
||||
|
||||
auto objectInfo = VLC->objtypeh->getHandlerFor(bank->ID, bank->subID)->getObjectInfo(bank->appearance);
|
||||
|
||||
CBankInfo * bankInfo = dynamic_cast<CBankInfo *> (objectInfo.get());
|
||||
CBankInfo * bankInfo = dynamic_cast<CBankInfo *>(objectInfo.get());
|
||||
|
||||
ui64 totalStrength = 0;
|
||||
ui8 totalChance = 0;
|
||||
for (auto config : bankInfo->getPossibleGuards())
|
||||
for(auto config : bankInfo->getPossibleGuards())
|
||||
{
|
||||
totalStrength += config.second.totalStrength * config.first;
|
||||
totalChance += config.first;
|
||||
@@ -222,7 +218,7 @@ ui64 FuzzyHelper::estimateBankDanger (const CBank * bank)
|
||||
|
||||
}
|
||||
|
||||
float FuzzyHelper::getTacticalAdvantage (const CArmedInstance *we, const CArmedInstance *enemy)
|
||||
float FuzzyHelper::getTacticalAdvantage(const CArmedInstance * we, const CArmedInstance * enemy)
|
||||
{
|
||||
float output = 1;
|
||||
try
|
||||
@@ -240,17 +236,15 @@ float FuzzyHelper::getTacticalAdvantage (const CArmedInstance *we, const CArmedI
|
||||
ta.enemyFlyers->setValue(enemyStructure.flyers);
|
||||
ta.enemySpeed->setValue(enemyStructure.maxSpeed);
|
||||
|
||||
bool bank = dynamic_cast<const CBank*> (enemy);
|
||||
if (bank)
|
||||
bool bank = dynamic_cast<const CBank *>(enemy);
|
||||
if(bank)
|
||||
ta.bankPresent->setValue(1);
|
||||
else
|
||||
ta.bankPresent->setValue(0);
|
||||
|
||||
const CGTownInstance * fort = dynamic_cast<const CGTownInstance*> (enemy);
|
||||
if (fort)
|
||||
{
|
||||
const CGTownInstance * fort = dynamic_cast<const CGTownInstance *>(enemy);
|
||||
if(fort)
|
||||
ta.castleWalls->setValue(fort->fortLevel());
|
||||
}
|
||||
else
|
||||
ta.castleWalls->setValue(0);
|
||||
|
||||
@@ -258,18 +252,18 @@ float FuzzyHelper::getTacticalAdvantage (const CArmedInstance *we, const CArmedI
|
||||
ta.engine.process();
|
||||
output = ta.threat->getValue();
|
||||
}
|
||||
catch (fl::Exception & fe)
|
||||
catch(fl::Exception & fe)
|
||||
{
|
||||
logAi->error("getTacticalAdvantage: %s ",fe.getWhat());
|
||||
logAi->error("getTacticalAdvantage: %s ", fe.getWhat());
|
||||
}
|
||||
|
||||
if (output < 0 || (output != output))
|
||||
if(output < 0 || (output != output))
|
||||
{
|
||||
fl::InputVariable* tab[] = {ta.bankPresent, ta.castleWalls, ta.ourWalkers, ta.ourShooters, ta.ourFlyers, ta.ourSpeed, ta.enemyWalkers, ta.enemyShooters, ta.enemyFlyers, ta.enemySpeed};
|
||||
fl::InputVariable * tab[] = {ta.bankPresent, ta.castleWalls, ta.ourWalkers, ta.ourShooters, ta.ourFlyers, ta.ourSpeed, ta.enemyWalkers, ta.enemyShooters, ta.enemyFlyers, ta.enemySpeed};
|
||||
std::string names[] = {"bankPresent", "castleWalls", "ourWalkers", "ourShooters", "ourFlyers", "ourSpeed", "enemyWalkers", "enemyShooters", "enemyFlyers", "enemySpeed" };
|
||||
std::stringstream log("Warning! Fuzzy engine doesn't cover this set of parameters: ");
|
||||
|
||||
for (int i = 0; i < boost::size(tab); i++)
|
||||
for(int i = 0; i < boost::size(tab); i++)
|
||||
log << names[i] << ": " << tab[i]->getValue() << " ";
|
||||
logAi->error(log.str());
|
||||
assert(false);
|
||||
@@ -296,9 +290,9 @@ FuzzyHelper::TacticalAdvantage::~TacticalAdvantage()
|
||||
|
||||
//std::shared_ptr<AbstractGoal> chooseSolution (std::vector<std::shared_ptr<AbstractGoal>> & vec)
|
||||
|
||||
Goals::TSubgoal FuzzyHelper::chooseSolution (Goals::TGoalVec vec)
|
||||
Goals::TSubgoal FuzzyHelper::chooseSolution(Goals::TGoalVec vec)
|
||||
{
|
||||
if (vec.empty()) //no possibilities found
|
||||
if(vec.empty()) //no possibilities found
|
||||
return sptr(Goals::Invalid());
|
||||
|
||||
ai->cachedSectorMaps.clear();
|
||||
@@ -308,9 +302,9 @@ Goals::TSubgoal FuzzyHelper::chooseSolution (Goals::TGoalVec vec)
|
||||
{
|
||||
return lhs->hero.h < rhs->hero.h;
|
||||
};
|
||||
boost::sort (vec, sortByHeroes);
|
||||
boost::sort(vec, sortByHeroes);
|
||||
|
||||
for (auto g : vec)
|
||||
for(auto g : vec)
|
||||
{
|
||||
setPriority(g);
|
||||
}
|
||||
@@ -319,16 +313,16 @@ Goals::TSubgoal FuzzyHelper::chooseSolution (Goals::TGoalVec vec)
|
||||
{
|
||||
return lhs->priority < rhs->priority;
|
||||
};
|
||||
boost::sort (vec, compareGoals);
|
||||
boost::sort(vec, compareGoals);
|
||||
|
||||
return vec.back();
|
||||
}
|
||||
|
||||
float FuzzyHelper::evaluate (Goals::Explore & g)
|
||||
float FuzzyHelper::evaluate(Goals::Explore & g)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
float FuzzyHelper::evaluate (Goals::RecruitHero & g)
|
||||
float FuzzyHelper::evaluate(Goals::RecruitHero & g)
|
||||
{
|
||||
return 1; //just try to recruit hero as one of options
|
||||
}
|
||||
@@ -354,8 +348,8 @@ void FuzzyHelper::initVisitTile()
|
||||
vt.value->setMinimum(0);
|
||||
vt.value->setMaximum(5);
|
||||
|
||||
std::vector<fl::InputVariable*> helper = {vt.strengthRatio, vt.heroStrength, vt.turnDistance, vt.missionImportance, vt.estimatedReward};
|
||||
for (auto val : helper)
|
||||
std::vector<fl::InputVariable *> helper = {vt.strengthRatio, vt.heroStrength, vt.turnDistance, vt.missionImportance, vt.estimatedReward};
|
||||
for(auto val : helper)
|
||||
{
|
||||
vt.engine.addInputVariable(val);
|
||||
}
|
||||
@@ -363,7 +357,7 @@ void FuzzyHelper::initVisitTile()
|
||||
|
||||
vt.strengthRatio->addTerm(new fl::Ramp("LOW", SAFE_ATTACK_CONSTANT, 0));
|
||||
vt.strengthRatio->addTerm(new fl::Ramp("HIGH", SAFE_ATTACK_CONSTANT, SAFE_ATTACK_CONSTANT * 3));
|
||||
vt.strengthRatio->setRange(0, SAFE_ATTACK_CONSTANT * 3 );
|
||||
vt.strengthRatio->setRange(0, SAFE_ATTACK_CONSTANT * 3);
|
||||
|
||||
//strength compared to our main hero
|
||||
vt.heroStrength->addTerm(new fl::Ramp("LOW", 0.2, 0));
|
||||
@@ -390,7 +384,7 @@ void FuzzyHelper::initVisitTile()
|
||||
vt.value->addTerm(new fl::Ramp("LOW", 2.5, 0));
|
||||
vt.value->addTerm(new fl::Triangle("MEDIUM", 2, 3)); //can't be center of mass :/
|
||||
vt.value->addTerm(new fl::Ramp("HIGH", 2.5, 5));
|
||||
vt.value->setRange(0.0,5.0);
|
||||
vt.value->setRange(0.0, 5.0);
|
||||
|
||||
//use unarmed scouts if possible
|
||||
vt.addRule("if strengthRatio is HIGH and heroStrength is LOW then Value is very HIGH");
|
||||
@@ -415,43 +409,47 @@ void FuzzyHelper::initVisitTile()
|
||||
vt.addRule("if estimatedReward is HIGH then Value is very HIGH");
|
||||
vt.addRule("if estimatedReward is LOW then Value is somewhat LOW");
|
||||
}
|
||||
catch (fl::Exception & fe)
|
||||
catch(fl::Exception & fe)
|
||||
{
|
||||
logAi->error("visitTile: %s",fe.getWhat());
|
||||
logAi->error("visitTile: %s", fe.getWhat());
|
||||
}
|
||||
}
|
||||
|
||||
float FuzzyHelper::evaluate (Goals::VisitTile & g)
|
||||
float FuzzyHelper::evaluate(Goals::VisitTile & g)
|
||||
{
|
||||
//we assume that hero is already set and we want to choose most suitable one for the mission
|
||||
if (!g.hero)
|
||||
if(!g.hero)
|
||||
return 0;
|
||||
|
||||
//assert(cb->isInTheMap(g.tile));
|
||||
float turns = 0;
|
||||
float distance = CPathfinderHelper::getMovementCost(g.hero.h, g.tile);
|
||||
if (!distance) //we stand on that tile
|
||||
if(!distance) //we stand on that tile
|
||||
{
|
||||
turns = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (distance < g.hero->movement) //we can move there within one turn
|
||||
if(distance < g.hero->movement) //we can move there within one turn
|
||||
turns = (fl::scalar)distance / g.hero->movement;
|
||||
else
|
||||
turns = 1 + (fl::scalar)(distance - g.hero->movement) / g.hero->maxMovePoints(true); //bool on land?
|
||||
}
|
||||
|
||||
float missionImportance = 0;
|
||||
if (vstd::contains(ai->lockedHeroes, g.hero))
|
||||
if(vstd::contains(ai->lockedHeroes, g.hero))
|
||||
missionImportance = ai->lockedHeroes[g.hero]->priority;
|
||||
|
||||
float strengthRatio = 10.0f; //we are much stronger than enemy
|
||||
ui64 danger = evaluateDanger (g.tile, g.hero.h);
|
||||
if (danger)
|
||||
ui64 danger = evaluateDanger(g.tile, g.hero.h);
|
||||
if(danger)
|
||||
strengthRatio = (fl::scalar)g.hero.h->getTotalStrength() / danger;
|
||||
|
||||
float tilePriority = 0;
|
||||
if(g.objid == -1)
|
||||
{
|
||||
vt.estimatedReward->setEnabled(false);
|
||||
}
|
||||
else if(g.objid == Obj::TOWN) //TODO: move to getObj eventually and add appropiate logic there
|
||||
{
|
||||
vt.estimatedReward->setEnabled(true);
|
||||
@@ -470,23 +468,23 @@ float FuzzyHelper::evaluate (Goals::VisitTile & g)
|
||||
//engine.process(VISIT_TILE); //TODO: Process only Visit_Tile
|
||||
g.priority = vt.value->getValue();
|
||||
}
|
||||
catch (fl::Exception & fe)
|
||||
catch(fl::Exception & fe)
|
||||
{
|
||||
logAi->error("evaluate VisitTile: %s",fe.getWhat());
|
||||
logAi->error("evaluate VisitTile: %s", fe.getWhat());
|
||||
}
|
||||
assert (g.priority >= 0);
|
||||
assert(g.priority >= 0);
|
||||
return g.priority;
|
||||
}
|
||||
float FuzzyHelper::evaluate (Goals::VisitHero & g)
|
||||
float FuzzyHelper::evaluate(Goals::VisitHero & g)
|
||||
{
|
||||
auto obj = cb->getObj(ObjectInstanceID(g.objid)); //we assume for now that these goals are similar
|
||||
if (!obj)
|
||||
if(!obj)
|
||||
return -100; //hero died in the meantime
|
||||
//TODO: consider direct copy (constructor?)
|
||||
g.setpriority(Goals::VisitTile(obj->visitablePos()).sethero(g.hero).setisAbstract(g.isAbstract).accept(this));
|
||||
return g.priority;
|
||||
}
|
||||
float FuzzyHelper::evaluate (Goals::GatherArmy & g)
|
||||
float FuzzyHelper::evaluate(Goals::GatherArmy & g)
|
||||
{
|
||||
//the more army we need, the more important goal
|
||||
//the more army we lack, the less important goal
|
||||
@@ -495,16 +493,16 @@ float FuzzyHelper::evaluate (Goals::GatherArmy & g)
|
||||
return 5 * (ratio / (ratio + 2)); //so 50% army gives 2.5, asymptotic 5
|
||||
}
|
||||
|
||||
float FuzzyHelper::evaluate (Goals::ClearWayTo & g)
|
||||
float FuzzyHelper::evaluate(Goals::ClearWayTo & g)
|
||||
{
|
||||
if (!g.hero.h)
|
||||
if(!g.hero.h)
|
||||
throw cannotFulfillGoalException("ClearWayTo called without hero!");
|
||||
|
||||
int3 t = ai->getCachedSectorMap(g.hero)->firstTileToGet(g.hero, g.tile);
|
||||
|
||||
if (t.valid())
|
||||
if(t.valid())
|
||||
{
|
||||
if (isSafeToVisit(g.hero, t))
|
||||
if(isSafeToVisit(g.hero, t))
|
||||
{
|
||||
g.setpriority(Goals::VisitTile(g.tile).sethero(g.hero).setisAbstract(g.isAbstract).accept(this));
|
||||
}
|
||||
@@ -520,32 +518,32 @@ float FuzzyHelper::evaluate (Goals::ClearWayTo & g)
|
||||
|
||||
}
|
||||
|
||||
float FuzzyHelper::evaluate (Goals::BuildThis & g)
|
||||
float FuzzyHelper::evaluate(Goals::BuildThis & g)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
float FuzzyHelper::evaluate (Goals::DigAtTile & g)
|
||||
float FuzzyHelper::evaluate(Goals::DigAtTile & g)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
float FuzzyHelper::evaluate (Goals::CollectRes & g)
|
||||
float FuzzyHelper::evaluate(Goals::CollectRes & g)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
float FuzzyHelper::evaluate (Goals::Build & g)
|
||||
float FuzzyHelper::evaluate(Goals::Build & g)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
float FuzzyHelper::evaluate (Goals::Invalid & g)
|
||||
float FuzzyHelper::evaluate(Goals::Invalid & g)
|
||||
{
|
||||
return -1e10;
|
||||
}
|
||||
float FuzzyHelper::evaluate (Goals::AbstractGoal & g)
|
||||
float FuzzyHelper::evaluate(Goals::AbstractGoal & g)
|
||||
{
|
||||
logAi->warn("Cannot evaluate goal %s", g.name());
|
||||
return g.priority;
|
||||
}
|
||||
void FuzzyHelper::setPriority (Goals::TSubgoal & g)
|
||||
void FuzzyHelper::setPriority(Goals::TSubgoal & g)
|
||||
{
|
||||
g->setpriority(g->accept(this)); //this enforces returned value is set
|
||||
}
|
||||
|
@@ -24,7 +24,7 @@ public:
|
||||
|
||||
engineBase();
|
||||
void configure();
|
||||
void addRule(const std::string &txt);
|
||||
void addRule(const std::string & txt);
|
||||
};
|
||||
|
||||
class FuzzyHelper
|
||||
@@ -65,23 +65,23 @@ public:
|
||||
void initTacticalAdvantage();
|
||||
void initVisitTile();
|
||||
|
||||
float evaluate (Goals::Explore & g);
|
||||
float evaluate (Goals::RecruitHero & g);
|
||||
float evaluate (Goals::VisitTile & g);
|
||||
float evaluate (Goals::VisitHero & g);
|
||||
float evaluate (Goals::BuildThis & g);
|
||||
float evaluate (Goals::DigAtTile & g);
|
||||
float evaluate (Goals::CollectRes & g);
|
||||
float evaluate (Goals::Build & g);
|
||||
float evaluate (Goals::GatherArmy & g);
|
||||
float evaluate (Goals::ClearWayTo & g);
|
||||
float evaluate (Goals::Invalid & g);
|
||||
float evaluate (Goals::AbstractGoal & g);
|
||||
void setPriority (Goals::TSubgoal & g);
|
||||
float evaluate(Goals::Explore & g);
|
||||
float evaluate(Goals::RecruitHero & g);
|
||||
float evaluate(Goals::VisitTile & g);
|
||||
float evaluate(Goals::VisitHero & g);
|
||||
float evaluate(Goals::BuildThis & g);
|
||||
float evaluate(Goals::DigAtTile & g);
|
||||
float evaluate(Goals::CollectRes & g);
|
||||
float evaluate(Goals::Build & g);
|
||||
float evaluate(Goals::GatherArmy & g);
|
||||
float evaluate(Goals::ClearWayTo & g);
|
||||
float evaluate(Goals::Invalid & g);
|
||||
float evaluate(Goals::AbstractGoal & g);
|
||||
void setPriority(Goals::TSubgoal & g);
|
||||
|
||||
ui64 estimateBankDanger (const CBank * bank);
|
||||
float getTacticalAdvantage (const CArmedInstance *we, const CArmedInstance *enemy); //returns factor how many times enemy is stronger than us
|
||||
ui64 estimateBankDanger(const CBank * bank);
|
||||
float getTacticalAdvantage(const CArmedInstance * we, const CArmedInstance * enemy); //returns factor how many times enemy is stronger than us
|
||||
|
||||
Goals::TSubgoal chooseSolution (Goals::TGoalVec vec);
|
||||
Goals::TSubgoal chooseSolution(Goals::TGoalVec vec);
|
||||
//std::shared_ptr<AbstractGoal> chooseSolution (std::vector<std::shared_ptr<AbstractGoal>> & vec);
|
||||
};
|
||||
|
File diff suppressed because it is too large
Load Diff
431
AI/VCAI/Goals.h
431
AI/VCAI/Goals.h
@@ -21,12 +21,12 @@ class FuzzyHelper;
|
||||
|
||||
namespace Goals
|
||||
{
|
||||
class AbstractGoal;
|
||||
class VisitTile;
|
||||
typedef std::shared_ptr<Goals::AbstractGoal> TSubgoal;
|
||||
typedef std::vector<TSubgoal> TGoalVec;
|
||||
class AbstractGoal;
|
||||
class VisitTile;
|
||||
typedef std::shared_ptr<Goals::AbstractGoal> TSubgoal;
|
||||
typedef std::vector<TSubgoal> TGoalVec;
|
||||
|
||||
enum EGoals
|
||||
enum EGoals
|
||||
{
|
||||
INVALID = -1,
|
||||
WIN, DO_NOT_LOSE, CONQUER, BUILD, //build needs to get a real reasoning
|
||||
@@ -78,7 +78,8 @@ public:
|
||||
const CGTownInstance *town; VSETTER(CGTownInstance *, town)
|
||||
int bid; VSETTER(int, bid)
|
||||
|
||||
AbstractGoal (EGoals goal = INVALID) : goalType (goal)
|
||||
AbstractGoal(EGoals goal = INVALID)
|
||||
: goalType (goal)
|
||||
{
|
||||
priority = 0;
|
||||
isElementar = false;
|
||||
@@ -91,35 +92,47 @@ public:
|
||||
town = nullptr;
|
||||
bid = -1;
|
||||
}
|
||||
virtual ~AbstractGoal(){};
|
||||
virtual ~AbstractGoal(){}
|
||||
//FIXME: abstract goal should be abstract, but serializer fails to instantiate subgoals in such case
|
||||
virtual AbstractGoal * clone() const {return const_cast<AbstractGoal*>(this);};
|
||||
virtual TGoalVec getAllPossibleSubgoals() {TGoalVec vec; return vec;};
|
||||
virtual TSubgoal whatToDoToAchieve() {return sptr(AbstractGoal());};
|
||||
virtual AbstractGoal * clone() const
|
||||
{
|
||||
return const_cast<AbstractGoal *>(this);
|
||||
}
|
||||
virtual TGoalVec getAllPossibleSubgoals()
|
||||
{
|
||||
return TGoalVec();
|
||||
}
|
||||
virtual TSubgoal whatToDoToAchieve()
|
||||
{
|
||||
return sptr(AbstractGoal());
|
||||
}
|
||||
|
||||
EGoals goalType;
|
||||
|
||||
std::string name() const;
|
||||
virtual std::string completeMessage() const {return "This goal is unspecified!";};
|
||||
virtual std::string completeMessage() const
|
||||
{
|
||||
return "This goal is unspecified!";
|
||||
}
|
||||
|
||||
bool invalid() const;
|
||||
|
||||
static TSubgoal goVisitOrLookFor(const CGObjectInstance *obj); //if obj is nullptr, then we'll explore
|
||||
static TSubgoal goVisitOrLookFor(const CGObjectInstance * obj); //if obj is nullptr, then we'll explore
|
||||
static TSubgoal lookForArtSmart(int aid); //checks non-standard ways of obtaining art (merchants, quests, etc.)
|
||||
static TSubgoal tryRecruitHero();
|
||||
|
||||
///Visitor pattern
|
||||
//TODO: make accept work for std::shared_ptr... somehow
|
||||
virtual void accept (VCAI * ai); //unhandled goal will report standard error
|
||||
virtual float accept (FuzzyHelper * f);
|
||||
virtual void accept(VCAI * ai); //unhandled goal will report standard error
|
||||
virtual float accept(FuzzyHelper * f);
|
||||
|
||||
virtual bool operator== (AbstractGoal &g);
|
||||
virtual bool fulfillsMe (Goals::TSubgoal goal) //TODO: multimethod instead of type check
|
||||
virtual bool operator==(AbstractGoal & g);
|
||||
virtual bool fulfillsMe(Goals::TSubgoal goal) //TODO: multimethod instead of type check
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
template<typename Handler> void serialize(Handler & h, const int version)
|
||||
{
|
||||
h & goalType;
|
||||
h & isElementar;
|
||||
@@ -136,10 +149,10 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T> class CGoal : public AbstractGoal
|
||||
template<typename T> class CGoal : public AbstractGoal
|
||||
{
|
||||
public:
|
||||
CGoal<T> (EGoals goal = INVALID) : AbstractGoal (goal)
|
||||
CGoal<T>(EGoals goal = INVALID) : AbstractGoal(goal)
|
||||
{
|
||||
priority = 0;
|
||||
isElementar = false;
|
||||
@@ -164,12 +177,12 @@ public:
|
||||
OSETTER(CGTownInstance *, town)
|
||||
OSETTER(int, bid)
|
||||
|
||||
void accept (VCAI * ai) override;
|
||||
float accept (FuzzyHelper * f) override;
|
||||
void accept(VCAI * ai) override;
|
||||
float accept(FuzzyHelper * f) override;
|
||||
|
||||
CGoal<T> * clone() const override
|
||||
{
|
||||
return new T(static_cast<T const&>(*this)); //casting enforces template instantiation
|
||||
return new T(static_cast<T const &>(*this)); //casting enforces template instantiation
|
||||
}
|
||||
TSubgoal iAmElementar()
|
||||
{
|
||||
@@ -178,9 +191,9 @@ public:
|
||||
ptr.reset(clone());
|
||||
return ptr;
|
||||
}
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
template<typename Handler> void serialize(Handler & h, const int version)
|
||||
{
|
||||
h & static_cast<AbstractGoal&> (*this);
|
||||
h & static_cast<AbstractGoal &>(*this);
|
||||
//h & goalType & isElementar & isAbstract & priority;
|
||||
//h & value & resID & objid & aid & tile & hero & town & bid;
|
||||
}
|
||||
@@ -188,189 +201,403 @@ public:
|
||||
|
||||
class Invalid : public CGoal<Invalid>
|
||||
{
|
||||
public:
|
||||
Invalid() : CGoal (Goals::INVALID) {priority = -1e10;};
|
||||
TGoalVec getAllPossibleSubgoals() override {return TGoalVec();};
|
||||
public:
|
||||
Invalid()
|
||||
: CGoal(Goals::INVALID)
|
||||
{
|
||||
priority = -1e10;
|
||||
}
|
||||
TGoalVec getAllPossibleSubgoals() override
|
||||
{
|
||||
return TGoalVec();
|
||||
}
|
||||
TSubgoal whatToDoToAchieve() override;
|
||||
};
|
||||
|
||||
class Win : public CGoal<Win>
|
||||
{
|
||||
public:
|
||||
Win() : CGoal (Goals::WIN) {priority = 100;};
|
||||
TGoalVec getAllPossibleSubgoals() override {return TGoalVec();};
|
||||
public:
|
||||
Win()
|
||||
: CGoal(Goals::WIN)
|
||||
{
|
||||
priority = 100;
|
||||
}
|
||||
TGoalVec getAllPossibleSubgoals() override
|
||||
{
|
||||
return TGoalVec();
|
||||
}
|
||||
TSubgoal whatToDoToAchieve() override;
|
||||
};
|
||||
|
||||
class NotLose : public CGoal<NotLose>
|
||||
{
|
||||
public:
|
||||
NotLose() : CGoal (Goals::DO_NOT_LOSE) {priority = 100;};
|
||||
TGoalVec getAllPossibleSubgoals() override {return TGoalVec();};
|
||||
public:
|
||||
NotLose()
|
||||
: CGoal(Goals::DO_NOT_LOSE)
|
||||
{
|
||||
priority = 100;
|
||||
}
|
||||
TGoalVec getAllPossibleSubgoals() override
|
||||
{
|
||||
return TGoalVec();
|
||||
}
|
||||
//TSubgoal whatToDoToAchieve() override;
|
||||
};
|
||||
|
||||
class Conquer : public CGoal<Conquer>
|
||||
{
|
||||
public:
|
||||
Conquer() : CGoal (Goals::CONQUER) {priority = 10;};
|
||||
public:
|
||||
Conquer()
|
||||
: CGoal(Goals::CONQUER)
|
||||
{
|
||||
priority = 10;
|
||||
}
|
||||
TGoalVec getAllPossibleSubgoals() override;
|
||||
TSubgoal whatToDoToAchieve() override;
|
||||
};
|
||||
|
||||
class Build : public CGoal<Build>
|
||||
{
|
||||
public:
|
||||
Build() : CGoal (Goals::BUILD) {priority = 1;};
|
||||
TGoalVec getAllPossibleSubgoals() override {return TGoalVec();};
|
||||
public:
|
||||
Build()
|
||||
: CGoal(Goals::BUILD)
|
||||
{
|
||||
priority = 1;
|
||||
}
|
||||
TGoalVec getAllPossibleSubgoals() override
|
||||
{
|
||||
return TGoalVec();
|
||||
}
|
||||
TSubgoal whatToDoToAchieve() override;
|
||||
};
|
||||
|
||||
class Explore : public CGoal<Explore>
|
||||
{
|
||||
public:
|
||||
Explore() : CGoal (Goals::EXPLORE){priority = 1;};
|
||||
Explore(HeroPtr h) : CGoal (Goals::EXPLORE){hero = h; priority = 1;};
|
||||
public:
|
||||
Explore()
|
||||
: CGoal(Goals::EXPLORE)
|
||||
{
|
||||
priority = 1;
|
||||
}
|
||||
Explore(HeroPtr h)
|
||||
: CGoal(Goals::EXPLORE)
|
||||
{
|
||||
hero = h;
|
||||
priority = 1;
|
||||
}
|
||||
TGoalVec getAllPossibleSubgoals() override;
|
||||
TSubgoal whatToDoToAchieve() override;
|
||||
std::string completeMessage() const override;
|
||||
bool fulfillsMe (TSubgoal goal) override;
|
||||
bool fulfillsMe(TSubgoal goal) override;
|
||||
};
|
||||
|
||||
class GatherArmy : public CGoal<GatherArmy>
|
||||
{
|
||||
public:
|
||||
GatherArmy() : CGoal (Goals::GATHER_ARMY){};
|
||||
|
||||
GatherArmy(int val) : CGoal (Goals::GATHER_ARMY){value = val; priority = 2.5;};
|
||||
GatherArmy()
|
||||
: CGoal(Goals::GATHER_ARMY)
|
||||
{
|
||||
}
|
||||
GatherArmy(int val)
|
||||
: CGoal(Goals::GATHER_ARMY)
|
||||
{
|
||||
value = val;
|
||||
priority = 2.5;
|
||||
}
|
||||
TGoalVec getAllPossibleSubgoals() override;
|
||||
TSubgoal whatToDoToAchieve() override;
|
||||
std::string completeMessage() const override;
|
||||
};
|
||||
|
||||
class BoostHero : public CGoal<BoostHero>
|
||||
{
|
||||
public:
|
||||
BoostHero() : CGoal (Goals::INVALID){priority = -1e10;}; //TODO
|
||||
TGoalVec getAllPossibleSubgoals() override {return TGoalVec();};
|
||||
public:
|
||||
BoostHero()
|
||||
: CGoal(Goals::INVALID)
|
||||
{
|
||||
priority = -1e10; //TODO
|
||||
}
|
||||
TGoalVec getAllPossibleSubgoals() override
|
||||
{
|
||||
return TGoalVec();
|
||||
}
|
||||
//TSubgoal whatToDoToAchieve() override {return sptr(Invalid());};
|
||||
};
|
||||
|
||||
class RecruitHero : public CGoal<RecruitHero>
|
||||
{
|
||||
public:
|
||||
RecruitHero() : CGoal (Goals::RECRUIT_HERO){priority = 1;};
|
||||
TGoalVec getAllPossibleSubgoals() override {return TGoalVec();};
|
||||
public:
|
||||
RecruitHero()
|
||||
: CGoal(Goals::RECRUIT_HERO)
|
||||
{
|
||||
priority = 1;
|
||||
}
|
||||
TGoalVec getAllPossibleSubgoals() override
|
||||
{
|
||||
return TGoalVec();
|
||||
}
|
||||
TSubgoal whatToDoToAchieve() override;
|
||||
};
|
||||
|
||||
class BuildThis : public CGoal<BuildThis>
|
||||
{
|
||||
public:
|
||||
BuildThis() : CGoal (Goals::BUILD_STRUCTURE){}; //FIXME: should be not allowed (private)
|
||||
|
||||
BuildThis(BuildingID Bid, const CGTownInstance *tid) : CGoal (Goals::BUILD_STRUCTURE) {bid = Bid; town = tid; priority = 5;};
|
||||
BuildThis(BuildingID Bid) : CGoal (Goals::BUILD_STRUCTURE) {bid = Bid; priority = 5;};
|
||||
TGoalVec getAllPossibleSubgoals() override {return TGoalVec();};
|
||||
BuildThis()
|
||||
: CGoal(Goals::BUILD_STRUCTURE)
|
||||
{
|
||||
//FIXME: should be not allowed (private)
|
||||
}
|
||||
BuildThis(BuildingID Bid, const CGTownInstance * tid)
|
||||
: CGoal(Goals::BUILD_STRUCTURE)
|
||||
{
|
||||
bid = Bid;
|
||||
town = tid;
|
||||
priority = 5;
|
||||
}
|
||||
BuildThis(BuildingID Bid)
|
||||
: CGoal(Goals::BUILD_STRUCTURE)
|
||||
{
|
||||
bid = Bid;
|
||||
priority = 5;
|
||||
}
|
||||
TGoalVec getAllPossibleSubgoals() override
|
||||
{
|
||||
return TGoalVec();
|
||||
}
|
||||
TSubgoal whatToDoToAchieve() override;
|
||||
};
|
||||
|
||||
class CollectRes : public CGoal<CollectRes>
|
||||
{
|
||||
public:
|
||||
CollectRes() : CGoal (Goals::COLLECT_RES){};
|
||||
|
||||
CollectRes(int rid, int val) : CGoal (Goals::COLLECT_RES) {resID = rid; value = val; priority = 2;};
|
||||
TGoalVec getAllPossibleSubgoals() override {return TGoalVec();};
|
||||
CollectRes()
|
||||
: CGoal(Goals::COLLECT_RES)
|
||||
{
|
||||
}
|
||||
CollectRes(int rid, int val)
|
||||
: CGoal(Goals::COLLECT_RES)
|
||||
{
|
||||
resID = rid;
|
||||
value = val;
|
||||
priority = 2;
|
||||
}
|
||||
TGoalVec getAllPossibleSubgoals() override
|
||||
{
|
||||
return TGoalVec();
|
||||
};
|
||||
TSubgoal whatToDoToAchieve() override;
|
||||
};
|
||||
|
||||
class GatherTroops : public CGoal<GatherTroops>
|
||||
{
|
||||
public:
|
||||
GatherTroops() : CGoal (Goals::GATHER_TROOPS){priority = 2;};
|
||||
|
||||
GatherTroops(int type, int val) : CGoal (Goals::GATHER_TROOPS){objid = type; value = val; priority = 2;};
|
||||
TGoalVec getAllPossibleSubgoals() override {return TGoalVec();};
|
||||
GatherTroops()
|
||||
: CGoal(Goals::GATHER_TROOPS)
|
||||
{
|
||||
priority = 2;
|
||||
}
|
||||
GatherTroops(int type, int val)
|
||||
: CGoal(Goals::GATHER_TROOPS)
|
||||
{
|
||||
objid = type;
|
||||
value = val;
|
||||
priority = 2;
|
||||
}
|
||||
TGoalVec getAllPossibleSubgoals() override
|
||||
{
|
||||
return TGoalVec();
|
||||
}
|
||||
TSubgoal whatToDoToAchieve() override;
|
||||
};
|
||||
|
||||
class GetObj : public CGoal<GetObj>
|
||||
{
|
||||
public:
|
||||
GetObj() {}; // empty constructor not allowed
|
||||
GetObj() {} // empty constructor not allowed
|
||||
|
||||
GetObj(int Objid) : CGoal(Goals::GET_OBJ) {objid = Objid; priority = 3;};
|
||||
TGoalVec getAllPossibleSubgoals() override {return TGoalVec();};
|
||||
GetObj(int Objid)
|
||||
: CGoal(Goals::GET_OBJ)
|
||||
{
|
||||
objid = Objid;
|
||||
priority = 3;
|
||||
}
|
||||
TGoalVec getAllPossibleSubgoals() override
|
||||
{
|
||||
return TGoalVec();
|
||||
}
|
||||
TSubgoal whatToDoToAchieve() override;
|
||||
bool operator== (GetObj &g) {return g.objid == objid;}
|
||||
bool fulfillsMe (TSubgoal goal) override;
|
||||
bool operator==(GetObj & g)
|
||||
{
|
||||
return g.objid == objid;
|
||||
}
|
||||
bool fulfillsMe(TSubgoal goal) override;
|
||||
std::string completeMessage() const override;
|
||||
};
|
||||
|
||||
class FindObj : public CGoal<FindObj>
|
||||
{
|
||||
public:
|
||||
FindObj() {}; // empty constructor not allowed
|
||||
FindObj() {} // empty constructor not allowed
|
||||
|
||||
FindObj(int ID) : CGoal(Goals::FIND_OBJ) {objid = ID; priority = 1;};
|
||||
FindObj(int ID, int subID) : CGoal(Goals::FIND_OBJ) {objid = ID; resID = subID; priority = 1;};
|
||||
TGoalVec getAllPossibleSubgoals() override {return TGoalVec();};
|
||||
FindObj(int ID)
|
||||
: CGoal(Goals::FIND_OBJ)
|
||||
{
|
||||
objid = ID;
|
||||
priority = 1;
|
||||
}
|
||||
FindObj(int ID, int subID)
|
||||
: CGoal(Goals::FIND_OBJ)
|
||||
{
|
||||
objid = ID;
|
||||
resID = subID;
|
||||
priority = 1;
|
||||
}
|
||||
TGoalVec getAllPossibleSubgoals() override
|
||||
{
|
||||
return TGoalVec();
|
||||
}
|
||||
TSubgoal whatToDoToAchieve() override;
|
||||
};
|
||||
|
||||
class VisitHero : public CGoal<VisitHero>
|
||||
{
|
||||
public:
|
||||
VisitHero() : CGoal (Goals::VISIT_HERO){};
|
||||
|
||||
VisitHero(int hid) : CGoal (Goals::VISIT_HERO){objid = hid; priority = 4;};
|
||||
TGoalVec getAllPossibleSubgoals() override {return TGoalVec();};
|
||||
VisitHero()
|
||||
: CGoal(Goals::VISIT_HERO)
|
||||
{
|
||||
}
|
||||
VisitHero(int hid)
|
||||
: CGoal(Goals::VISIT_HERO)
|
||||
{
|
||||
objid = hid;
|
||||
priority = 4;
|
||||
}
|
||||
TGoalVec getAllPossibleSubgoals() override
|
||||
{
|
||||
return TGoalVec();
|
||||
}
|
||||
TSubgoal whatToDoToAchieve() override;
|
||||
bool operator== (VisitHero &g) { return g.goalType == goalType && g.objid == objid; }
|
||||
bool fulfillsMe (TSubgoal goal) override;
|
||||
bool operator==(VisitHero & g)
|
||||
{
|
||||
return g.goalType == goalType && g.objid == objid;
|
||||
}
|
||||
bool fulfillsMe(TSubgoal goal) override;
|
||||
std::string completeMessage() const override;
|
||||
};
|
||||
|
||||
class GetArtOfType : public CGoal<GetArtOfType>
|
||||
{
|
||||
public:
|
||||
GetArtOfType() : CGoal (Goals::GET_ART_TYPE){};
|
||||
|
||||
GetArtOfType(int type) : CGoal (Goals::GET_ART_TYPE){aid = type; priority = 2;};
|
||||
TGoalVec getAllPossibleSubgoals() override {return TGoalVec();};
|
||||
GetArtOfType()
|
||||
: CGoal(Goals::GET_ART_TYPE)
|
||||
{
|
||||
}
|
||||
GetArtOfType(int type)
|
||||
: CGoal(Goals::GET_ART_TYPE)
|
||||
{
|
||||
aid = type;
|
||||
priority = 2;
|
||||
}
|
||||
TGoalVec getAllPossibleSubgoals() override
|
||||
{
|
||||
return TGoalVec();
|
||||
}
|
||||
TSubgoal whatToDoToAchieve() override;
|
||||
};
|
||||
|
||||
class VisitTile : public CGoal<VisitTile>
|
||||
//tile, in conjunction with hero elementar; assumes tile is reachable
|
||||
{
|
||||
public:
|
||||
VisitTile() {}; // empty constructor not allowed
|
||||
VisitTile() {} // empty constructor not allowed
|
||||
|
||||
VisitTile(int3 Tile) : CGoal (Goals::VISIT_TILE) {tile = Tile; priority = 5;};
|
||||
VisitTile(int3 Tile)
|
||||
: CGoal(Goals::VISIT_TILE)
|
||||
{
|
||||
tile = Tile;
|
||||
priority = 5;
|
||||
}
|
||||
TGoalVec getAllPossibleSubgoals() override;
|
||||
TSubgoal whatToDoToAchieve() override;
|
||||
bool operator== (VisitTile &g) { return g.goalType == goalType && g.tile == tile; }
|
||||
bool operator==(VisitTile & g)
|
||||
{
|
||||
return g.goalType == goalType && g.tile == tile;
|
||||
}
|
||||
std::string completeMessage() const override;
|
||||
};
|
||||
|
||||
class ClearWayTo : public CGoal<ClearWayTo>
|
||||
{
|
||||
public:
|
||||
ClearWayTo() : CGoal (Goals::CLEAR_WAY_TO){};
|
||||
|
||||
ClearWayTo(int3 Tile) : CGoal (Goals::CLEAR_WAY_TO) {tile = Tile; priority = 5;};
|
||||
ClearWayTo(int3 Tile, HeroPtr h) : CGoal (Goals::CLEAR_WAY_TO) {tile = Tile; hero = h; priority = 5;};
|
||||
ClearWayTo()
|
||||
: CGoal(Goals::CLEAR_WAY_TO)
|
||||
{
|
||||
}
|
||||
ClearWayTo(int3 Tile)
|
||||
: CGoal(Goals::CLEAR_WAY_TO)
|
||||
{
|
||||
tile = Tile;
|
||||
priority = 5;
|
||||
}
|
||||
ClearWayTo(int3 Tile, HeroPtr h)
|
||||
: CGoal(Goals::CLEAR_WAY_TO)
|
||||
{
|
||||
tile = Tile;
|
||||
hero = h;
|
||||
priority = 5;
|
||||
}
|
||||
TGoalVec getAllPossibleSubgoals() override;
|
||||
TSubgoal whatToDoToAchieve() override;
|
||||
bool operator== (ClearWayTo &g) { return g.goalType == goalType && g.tile == tile; }
|
||||
bool operator==(ClearWayTo & g)
|
||||
{
|
||||
return g.goalType == goalType && g.tile == tile;
|
||||
}
|
||||
};
|
||||
|
||||
class DigAtTile : public CGoal<DigAtTile>
|
||||
//elementar with hero on tile
|
||||
{
|
||||
public:
|
||||
DigAtTile() : CGoal (Goals::DIG_AT_TILE){};
|
||||
|
||||
DigAtTile(int3 Tile) : CGoal (Goals::DIG_AT_TILE) {tile = Tile; priority = 20;};
|
||||
TGoalVec getAllPossibleSubgoals() override {return TGoalVec();};
|
||||
DigAtTile()
|
||||
: CGoal(Goals::DIG_AT_TILE)
|
||||
{
|
||||
}
|
||||
DigAtTile(int3 Tile)
|
||||
: CGoal(Goals::DIG_AT_TILE)
|
||||
{
|
||||
tile = Tile;
|
||||
priority = 20;
|
||||
}
|
||||
TGoalVec getAllPossibleSubgoals() override
|
||||
{
|
||||
return TGoalVec();
|
||||
}
|
||||
TSubgoal whatToDoToAchieve() override;
|
||||
bool operator== (DigAtTile &g) { return g.goalType == goalType && g.tile == tile; }
|
||||
bool operator==(DigAtTile & g)
|
||||
{
|
||||
return g.goalType == goalType && g.tile == tile;
|
||||
}
|
||||
};
|
||||
|
||||
class CIssueCommand : public CGoal<CIssueCommand>
|
||||
{
|
||||
std::function<bool()> command;
|
||||
|
||||
public:
|
||||
CIssueCommand(): CGoal(ISSUE_COMMAND){};
|
||||
|
||||
CIssueCommand(std::function<bool()> _command): CGoal(ISSUE_COMMAND), command(_command) {priority = 1e10;};
|
||||
TGoalVec getAllPossibleSubgoals() override {return TGoalVec();};
|
||||
//TSubgoal whatToDoToAchieve() override {return sptr(Invalid());};
|
||||
public:
|
||||
CIssueCommand()
|
||||
: CGoal(ISSUE_COMMAND)
|
||||
{
|
||||
}
|
||||
CIssueCommand(std::function<bool()> _command)
|
||||
: CGoal(ISSUE_COMMAND), command(_command)
|
||||
{
|
||||
priority = 1e10;
|
||||
}
|
||||
TGoalVec getAllPossibleSubgoals() override
|
||||
{
|
||||
return TGoalVec();
|
||||
}
|
||||
//TSubgoal whatToDoToAchieve() override {return sptr(Invalid());}
|
||||
};
|
||||
|
||||
}
|
||||
|
1070
AI/VCAI/VCAI.cpp
1070
AI/VCAI/VCAI.cpp
File diff suppressed because it is too large
Load Diff
165
AI/VCAI/VCAI.h
165
AI/VCAI/VCAI.h
@@ -35,7 +35,7 @@ class AIStatus
|
||||
BattleState battle;
|
||||
std::map<QueryID, std::string> remainingQueries;
|
||||
std::map<int, QueryID> requestToQueryID; //IDs of answer-requests sent to server => query ids (so we can match answer confirmation from server to the query)
|
||||
std::vector<const CGObjectInstance*> objectsBeingVisited;
|
||||
std::vector<const CGObjectInstance *> objectsBeingVisited;
|
||||
bool ongoingHeroMovement;
|
||||
bool ongoingChannelProbing; // true if AI currently explore bidirectional teleport channel exits
|
||||
|
||||
@@ -58,10 +58,10 @@ public:
|
||||
bool haveTurn();
|
||||
void attemptedAnsweringQuery(QueryID queryID, int answerRequestID);
|
||||
void receivedAnswerConfirmation(int answerRequestID, int result);
|
||||
void heroVisit(const CGObjectInstance *obj, bool started);
|
||||
void heroVisit(const CGObjectInstance * obj, bool started);
|
||||
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
template<typename Handler> void serialize(Handler & h, const int version)
|
||||
{
|
||||
h & battle;
|
||||
h & remainingQueries;
|
||||
@@ -70,7 +70,12 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
enum {NOT_VISIBLE = 0, NOT_CHECKED = 1, NOT_AVAILABLE};
|
||||
enum
|
||||
{
|
||||
NOT_VISIBLE = 0,
|
||||
NOT_CHECKED = 1,
|
||||
NOT_AVAILABLE
|
||||
};
|
||||
|
||||
struct SectorMap
|
||||
{
|
||||
@@ -98,7 +103,7 @@ struct SectorMap
|
||||
//std::vector<std::vector<std::vector<unsigned char>>> pathfinderSector;
|
||||
|
||||
std::map<int, Sector> infoOnSectors;
|
||||
std::shared_ptr<boost::multi_array<TerrainTile*, 3>> visibleTiles;
|
||||
std::shared_ptr<boost::multi_array<TerrainTile *, 3>> visibleTiles;
|
||||
|
||||
SectorMap();
|
||||
SectorMap(HeroPtr h);
|
||||
@@ -107,12 +112,12 @@ struct SectorMap
|
||||
void exploreNewSector(crint3 pos, int num, CCallback * cbp);
|
||||
void write(crstring fname);
|
||||
|
||||
bool markIfBlocked(TSectorID &sec, crint3 pos, const TerrainTile *t);
|
||||
bool markIfBlocked(TSectorID &sec, crint3 pos);
|
||||
bool markIfBlocked(TSectorID & sec, crint3 pos, const TerrainTile * t);
|
||||
bool markIfBlocked(TSectorID & sec, crint3 pos);
|
||||
TSectorID & retrieveTile(crint3 pos);
|
||||
TSectorID & retrieveTileN(TSectorArray & vectors, const int3 & pos);
|
||||
const TSectorID & retrieveTileN(const TSectorArray &vectors, const int3 &pos);
|
||||
TerrainTile* getTile(crint3 pos) const;
|
||||
const TSectorID & retrieveTileN(const TSectorArray & vectors, const int3 & pos);
|
||||
TerrainTile * getTile(crint3 pos) const;
|
||||
std::vector<const CGObjectInstance *> getNearbyObjs(HeroPtr h, bool sectorsAround);
|
||||
|
||||
void makeParentBFS(crint3 source);
|
||||
@@ -128,25 +133,25 @@ public:
|
||||
|
||||
//try build an unbuilt structure in maxDays at most (0 = indefinite)
|
||||
/*bool canBuildStructure(const CGTownInstance * t, BuildingID building, unsigned int maxDays=7);*/
|
||||
bool tryBuildStructure(const CGTownInstance * t, BuildingID building, unsigned int maxDays=7);
|
||||
bool tryBuildStructure(const CGTownInstance * t, BuildingID building, unsigned int maxDays = 7);
|
||||
//try build ANY unbuilt structure
|
||||
BuildingID canBuildAnyStructure(const CGTownInstance * t, std::vector<BuildingID> buildList, unsigned int maxDays=7);
|
||||
bool tryBuildAnyStructure(const CGTownInstance * t, std::vector<BuildingID> buildList, unsigned int maxDays=7);
|
||||
BuildingID canBuildAnyStructure(const CGTownInstance * t, std::vector<BuildingID> buildList, unsigned int maxDays = 7);
|
||||
bool tryBuildAnyStructure(const CGTownInstance * t, std::vector<BuildingID> buildList, unsigned int maxDays = 7);
|
||||
//try build first unbuilt structure
|
||||
bool tryBuildNextStructure(const CGTownInstance * t, std::vector<BuildingID> buildList, unsigned int maxDays=7);
|
||||
bool tryBuildNextStructure(const CGTownInstance * t, std::vector<BuildingID> buildList, unsigned int maxDays = 7);
|
||||
|
||||
friend class FuzzyHelper;
|
||||
|
||||
std::map<TeleportChannelID, std::shared_ptr<TeleportChannel> > knownTeleportChannels;
|
||||
std::map<TeleportChannelID, std::shared_ptr<TeleportChannel>> knownTeleportChannels;
|
||||
std::map<const CGObjectInstance *, const CGObjectInstance *> knownSubterraneanGates;
|
||||
ObjectInstanceID destinationTeleport;
|
||||
int3 destinationTeleportPos;
|
||||
std::vector<ObjectInstanceID> teleportChannelProbingList; //list of teleport channel exits that not visible and need to be (re-)explored
|
||||
//std::vector<const CGObjectInstance *> visitedThisWeek; //only OPWs
|
||||
std::map<HeroPtr, std::set<const CGTownInstance *> > townVisitsThisWeek;
|
||||
std::map<HeroPtr, std::set<const CGTownInstance *>> townVisitsThisWeek;
|
||||
|
||||
std::map<HeroPtr, Goals::TSubgoal> lockedHeroes; //TODO: allow non-elementar objectives
|
||||
std::map<HeroPtr, std::set<const CGObjectInstance *> > reservedHeroesMap; //objects reserved by specific heroes
|
||||
std::map<HeroPtr, std::set<const CGObjectInstance *>> reservedHeroesMap; //objects reserved by specific heroes
|
||||
std::set<HeroPtr> heroesUnableToExplore; //these heroes will not be polled for exploration in current state of game
|
||||
|
||||
//sets are faster to search, also do not contain duplicates
|
||||
@@ -154,7 +159,7 @@ public:
|
||||
std::set<const CGObjectInstance *> alreadyVisited;
|
||||
std::set<const CGObjectInstance *> reservedObjs; //to be visited by specific hero
|
||||
|
||||
std::map <HeroPtr, std::shared_ptr<SectorMap>> cachedSectorMaps; //TODO: serialize? not necessary
|
||||
std::map<HeroPtr, std::shared_ptr<SectorMap>> cachedSectorMaps; //TODO: serialize? not necessary
|
||||
|
||||
TResources saving;
|
||||
|
||||
@@ -191,62 +196,62 @@ public:
|
||||
virtual void init(std::shared_ptr<CCallback> CB) override;
|
||||
virtual void yourTurn() override;
|
||||
|
||||
virtual void heroGotLevel(const CGHeroInstance *hero, PrimarySkill::PrimarySkill pskill, std::vector<SecondarySkill> &skills, QueryID queryID) override; //pskill is gained primary skill, interface has to choose one of given skills and call callback with selection id
|
||||
virtual void commanderGotLevel (const CCommanderInstance * commander, std::vector<ui32> skills, QueryID queryID) override; //TODO
|
||||
virtual void showBlockingDialog(const std::string &text, const std::vector<Component> &components, QueryID askID, const int soundID, bool selection, bool cancel) override; //Show a dialog, player must take decision. If selection then he has to choose between one of given components, if cancel he is allowed to not choose. After making choice, CCallback::selectionMade should be called with number of selected component (1 - n) or 0 for cancel (if allowed) and askID.
|
||||
virtual void showGarrisonDialog(const CArmedInstance *up, const CGHeroInstance *down, bool removableUnits, QueryID queryID) override; //all stacks operations between these objects become allowed, interface has to call onEnd when done
|
||||
virtual void heroGotLevel(const CGHeroInstance * hero, PrimarySkill::PrimarySkill pskill, std::vector<SecondarySkill> & skills, QueryID queryID) override; //pskill is gained primary skill, interface has to choose one of given skills and call callback with selection id
|
||||
virtual void commanderGotLevel(const CCommanderInstance * commander, std::vector<ui32> skills, QueryID queryID) override; //TODO
|
||||
virtual void showBlockingDialog(const std::string & text, const std::vector<Component> & components, QueryID askID, const int soundID, bool selection, bool cancel) override; //Show a dialog, player must take decision. If selection then he has to choose between one of given components, if cancel he is allowed to not choose. After making choice, CCallback::selectionMade should be called with number of selected component (1 - n) or 0 for cancel (if allowed) and askID.
|
||||
virtual void showGarrisonDialog(const CArmedInstance * up, const CGHeroInstance * down, bool removableUnits, QueryID queryID) override; //all stacks operations between these objects become allowed, interface has to call onEnd when done
|
||||
virtual void showTeleportDialog(TeleportChannelID channel, TTeleportExitsList exits, bool impassable, QueryID askID) override;
|
||||
void showMapObjectSelectDialog(QueryID askID, const Component & icon, const MetaString & title, const MetaString & description, const std::vector<ObjectInstanceID> & objects) override;
|
||||
virtual void saveGame(BinarySerializer & h, const int version) override; //saving
|
||||
virtual void loadGame(BinaryDeserializer & h, const int version) override; //loading
|
||||
virtual void finish() override;
|
||||
|
||||
virtual void availableCreaturesChanged(const CGDwelling *town) override;
|
||||
virtual void availableCreaturesChanged(const CGDwelling * town) override;
|
||||
virtual void heroMoved(const TryMoveHero & details) override;
|
||||
virtual void heroInGarrisonChange(const CGTownInstance *town) override;
|
||||
virtual void heroInGarrisonChange(const CGTownInstance * town) override;
|
||||
virtual void centerView(int3 pos, int focusTime) override;
|
||||
virtual void tileHidden(const std::unordered_set<int3, ShashInt3> &pos) override;
|
||||
virtual void artifactMoved(const ArtifactLocation &src, const ArtifactLocation &dst) override;
|
||||
virtual void artifactAssembled(const ArtifactLocation &al) override;
|
||||
virtual void showTavernWindow(const CGObjectInstance *townOrTavern) override;
|
||||
virtual void showThievesGuildWindow (const CGObjectInstance * obj) override;
|
||||
virtual void tileHidden(const std::unordered_set<int3, ShashInt3> & pos) override;
|
||||
virtual void artifactMoved(const ArtifactLocation & src, const ArtifactLocation & dst) override;
|
||||
virtual void artifactAssembled(const ArtifactLocation & al) override;
|
||||
virtual void showTavernWindow(const CGObjectInstance * townOrTavern) override;
|
||||
virtual void showThievesGuildWindow(const CGObjectInstance * obj) override;
|
||||
virtual void playerBlocked(int reason, bool start) override;
|
||||
virtual void showPuzzleMap() override;
|
||||
virtual void showShipyardDialog(const IShipyard *obj) override;
|
||||
virtual void showShipyardDialog(const IShipyard * obj) override;
|
||||
virtual void gameOver(PlayerColor player, const EVictoryLossCheckResult & victoryLossCheckResult) override;
|
||||
virtual void artifactPut(const ArtifactLocation &al) override;
|
||||
virtual void artifactRemoved(const ArtifactLocation &al) override;
|
||||
virtual void artifactDisassembled(const ArtifactLocation &al) override;
|
||||
virtual void heroVisit(const CGHeroInstance *visitor, const CGObjectInstance *visitedObj, bool start) override;
|
||||
virtual void availableArtifactsChanged(const CGBlackMarket *bm = nullptr) override;
|
||||
virtual void heroVisitsTown(const CGHeroInstance* hero, const CGTownInstance * town) override;
|
||||
virtual void tileRevealed(const std::unordered_set<int3, ShashInt3> &pos) override;
|
||||
virtual void artifactPut(const ArtifactLocation & al) override;
|
||||
virtual void artifactRemoved(const ArtifactLocation & al) override;
|
||||
virtual void artifactDisassembled(const ArtifactLocation & al) override;
|
||||
virtual void heroVisit(const CGHeroInstance * visitor, const CGObjectInstance * visitedObj, bool start) override;
|
||||
virtual void availableArtifactsChanged(const CGBlackMarket * bm = nullptr) override;
|
||||
virtual void heroVisitsTown(const CGHeroInstance * hero, const CGTownInstance * town) override;
|
||||
virtual void tileRevealed(const std::unordered_set<int3, ShashInt3> & pos) override;
|
||||
virtual void heroExchangeStarted(ObjectInstanceID hero1, ObjectInstanceID hero2, QueryID query) override;
|
||||
virtual void heroPrimarySkillChanged(const CGHeroInstance * hero, int which, si64 val) override;
|
||||
virtual void showRecruitmentDialog(const CGDwelling *dwelling, const CArmedInstance *dst, int level) override;
|
||||
virtual void showRecruitmentDialog(const CGDwelling * dwelling, const CArmedInstance * dst, int level) override;
|
||||
virtual void heroMovePointsChanged(const CGHeroInstance * hero) override;
|
||||
virtual void garrisonsChanged(ObjectInstanceID id1, ObjectInstanceID id2) override;
|
||||
virtual void newObject(const CGObjectInstance * obj) override;
|
||||
virtual void showHillFortWindow(const CGObjectInstance *object, const CGHeroInstance *visitor) override;
|
||||
virtual void playerBonusChanged(const Bonus &bonus, bool gain) override;
|
||||
virtual void heroCreated(const CGHeroInstance*) override;
|
||||
virtual void showHillFortWindow(const CGObjectInstance * object, const CGHeroInstance * visitor) override;
|
||||
virtual void playerBonusChanged(const Bonus & bonus, bool gain) override;
|
||||
virtual void heroCreated(const CGHeroInstance *) override;
|
||||
virtual void advmapSpellCast(const CGHeroInstance * caster, int spellID) override;
|
||||
virtual void showInfoDialog(const std::string &text, const std::vector<Component> &components, int soundID) override;
|
||||
virtual void requestRealized(PackageApplied *pa) override;
|
||||
virtual void showInfoDialog(const std::string & text, const std::vector<Component> & components, int soundID) override;
|
||||
virtual void requestRealized(PackageApplied * pa) override;
|
||||
virtual void receivedResource() override;
|
||||
virtual void objectRemoved(const CGObjectInstance *obj) override;
|
||||
virtual void showUniversityWindow(const IMarket *market, const CGHeroInstance *visitor) override;
|
||||
virtual void objectRemoved(const CGObjectInstance * obj) override;
|
||||
virtual void showUniversityWindow(const IMarket * market, const CGHeroInstance * visitor) override;
|
||||
virtual void heroManaPointsChanged(const CGHeroInstance * hero) override;
|
||||
virtual void heroSecondarySkillChanged(const CGHeroInstance * hero, int which, int val) override;
|
||||
virtual void battleResultsApplied() override;
|
||||
virtual void objectPropertyChanged(const SetObjectProperty * sop) override;
|
||||
virtual void buildChanged(const CGTownInstance *town, BuildingID buildingID, int what) override;
|
||||
virtual void heroBonusChanged(const CGHeroInstance *hero, const Bonus &bonus, bool gain) override;
|
||||
virtual void showMarketWindow(const IMarket *market, const CGHeroInstance *visitor) override;
|
||||
virtual void buildChanged(const CGTownInstance * town, BuildingID buildingID, int what) override;
|
||||
virtual void heroBonusChanged(const CGHeroInstance * hero, const Bonus & bonus, bool gain) override;
|
||||
virtual void showMarketWindow(const IMarket * market, const CGHeroInstance * visitor) override;
|
||||
void showWorldViewEx(const std::vector<ObjectPosInfo> & objectPositions) override;
|
||||
|
||||
virtual void battleStart(const CCreatureSet *army1, const CCreatureSet *army2, int3 tile, const CGHeroInstance *hero1, const CGHeroInstance *hero2, bool side) override;
|
||||
virtual void battleEnd(const BattleResult *br) override;
|
||||
virtual void battleStart(const CCreatureSet * army1, const CCreatureSet * army2, int3 tile, const CGHeroInstance * hero1, const CGHeroInstance * hero2, bool side) override;
|
||||
virtual void battleEnd(const BattleResult * br) override;
|
||||
void makeTurn();
|
||||
|
||||
void makeTurnInternal();
|
||||
@@ -259,15 +264,15 @@ public:
|
||||
void wander(HeroPtr h);
|
||||
void setGoal(HeroPtr h, Goals::TSubgoal goal);
|
||||
void evaluateGoal(HeroPtr h); //evaluates goal assigned to hero, if any
|
||||
void completeGoal (Goals::TSubgoal goal); //safely removes goal from reserved hero
|
||||
void striveToQuest (const QuestInfo &q);
|
||||
void completeGoal(Goals::TSubgoal goal); //safely removes goal from reserved hero
|
||||
void striveToQuest(const QuestInfo & q);
|
||||
|
||||
void recruitHero(const CGTownInstance * t, bool throwing = false);
|
||||
bool isGoodForVisit(const CGObjectInstance *obj, HeroPtr h, SectorMap &sm);
|
||||
bool isGoodForVisit(const CGObjectInstance * obj, HeroPtr h, SectorMap & sm);
|
||||
void buildStructure(const CGTownInstance * t);
|
||||
//void recruitCreatures(const CGTownInstance * t);
|
||||
void recruitCreatures(const CGDwelling * d, const CArmedInstance * recruiter);
|
||||
bool canGetArmy (const CGHeroInstance * h, const CGHeroInstance * source); //can we get any better stacks from other hero?
|
||||
bool canGetArmy(const CGHeroInstance * h, const CGHeroInstance * source); //can we get any better stacks from other hero?
|
||||
void pickBestCreatures(const CArmedInstance * army, const CArmedInstance * source); //called when we can't find a slot for new stack
|
||||
void pickBestArtifacts(const CGHeroInstance * h, const CGHeroInstance * other = nullptr);
|
||||
void moveCreaturesToHero(const CGTownInstance * t);
|
||||
@@ -279,52 +284,52 @@ public:
|
||||
void lostHero(HeroPtr h); //should remove all references to hero (assigned tasks and so on)
|
||||
void waitTillFree();
|
||||
|
||||
void addVisitableObj(const CGObjectInstance *obj);
|
||||
void markObjectVisited (const CGObjectInstance *obj);
|
||||
void reserveObject (HeroPtr h, const CGObjectInstance *obj); //TODO: reserve all objects that heroes attempt to visit
|
||||
void unreserveObject (HeroPtr h, const CGObjectInstance *obj);
|
||||
void addVisitableObj(const CGObjectInstance * obj);
|
||||
void markObjectVisited(const CGObjectInstance * obj);
|
||||
void reserveObject(HeroPtr h, const CGObjectInstance * obj); //TODO: reserve all objects that heroes attempt to visit
|
||||
void unreserveObject(HeroPtr h, const CGObjectInstance * obj);
|
||||
|
||||
void markHeroUnableToExplore (HeroPtr h);
|
||||
void markHeroAbleToExplore (HeroPtr h);
|
||||
bool isAbleToExplore (HeroPtr h);
|
||||
void markHeroUnableToExplore(HeroPtr h);
|
||||
void markHeroAbleToExplore(HeroPtr h);
|
||||
bool isAbleToExplore(HeroPtr h);
|
||||
void clearPathsInfo();
|
||||
|
||||
void validateObject(const CGObjectInstance *obj); //checks if object is still visible and if not, removes references to it
|
||||
void validateObject(const CGObjectInstance * obj); //checks if object is still visible and if not, removes references to it
|
||||
void validateObject(ObjectIdRef obj); //checks if object is still visible and if not, removes references to it
|
||||
void validateVisitableObjs();
|
||||
void retrieveVisitableObjs(std::vector<const CGObjectInstance *> &out, bool includeOwned = false) const;
|
||||
void retrieveVisitableObjs(std::vector<const CGObjectInstance *> & out, bool includeOwned = false) const;
|
||||
void retrieveVisitableObjs();
|
||||
std::vector<const CGObjectInstance *> getFlaggedObjects() const;
|
||||
|
||||
const CGObjectInstance *lookForArt(int aid) const;
|
||||
bool isAccessible(const int3 &pos);
|
||||
const CGObjectInstance * lookForArt(int aid) const;
|
||||
bool isAccessible(const int3 & pos);
|
||||
HeroPtr getHeroWithGrail() const;
|
||||
|
||||
const CGObjectInstance *getUnvisitedObj(const std::function<bool(const CGObjectInstance *)> &predicate);
|
||||
const CGObjectInstance * getUnvisitedObj(const std::function<bool(const CGObjectInstance *)> & predicate);
|
||||
bool isAccessibleForHero(const int3 & pos, HeroPtr h, bool includeAllies = false) const;
|
||||
//optimization - use one SM for every hero call
|
||||
std::shared_ptr<SectorMap> getCachedSectorMap(HeroPtr h);
|
||||
|
||||
const CGTownInstance *findTownWithTavern() const;
|
||||
const CGTownInstance * findTownWithTavern() const;
|
||||
bool canRecruitAnyHero(const CGTownInstance * t = NULL) const;
|
||||
|
||||
Goals::TSubgoal getGoal (HeroPtr h) const;
|
||||
Goals::TSubgoal getGoal(HeroPtr h) const;
|
||||
bool canAct(HeroPtr h) const;
|
||||
std::vector<HeroPtr> getUnblockedHeroes() const;
|
||||
HeroPtr primaryHero() const;
|
||||
TResources freeResources() const; //owned resources minus gold reserve
|
||||
TResources estimateIncome() const;
|
||||
bool containsSavedRes(const TResources &cost) const;
|
||||
void checkHeroArmy (HeroPtr h);
|
||||
bool containsSavedRes(const TResources & cost) const;
|
||||
void checkHeroArmy(HeroPtr h);
|
||||
|
||||
void requestSent(const CPackForServer *pack, int requestID) override;
|
||||
void requestSent(const CPackForServer * pack, int requestID) override;
|
||||
void answerQuery(QueryID queryID, int selection);
|
||||
//special function that can be called ONLY from game events handling thread and will send request ASAP
|
||||
void requestActionASAP(std::function<void()> whatToDo);
|
||||
|
||||
#if 0
|
||||
//disabled due to issue 2890
|
||||
template <typename Handler> void registerGoals(Handler &h)
|
||||
template<typename Handler> void registerGoals(Handler & h)
|
||||
{
|
||||
//h.template registerType<Goals::AbstractGoal, Goals::BoostHero>();
|
||||
h.template registerType<Goals::AbstractGoal, Goals::Build>();
|
||||
@@ -349,7 +354,7 @@ public:
|
||||
}
|
||||
#endif
|
||||
|
||||
template <typename Handler> void serializeInternal(Handler &h, const int version)
|
||||
template<typename Handler> void serializeInternal(Handler & h, const int version)
|
||||
{
|
||||
h & knownTeleportChannels;
|
||||
h & knownSubterraneanGates;
|
||||
@@ -413,8 +418,10 @@ public:
|
||||
class cannotFulfillGoalException : public std::exception
|
||||
{
|
||||
std::string msg;
|
||||
|
||||
public:
|
||||
explicit cannotFulfillGoalException(crstring _Message) : msg(_Message)
|
||||
explicit cannotFulfillGoalException(crstring _Message)
|
||||
: msg(_Message)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -422,18 +429,21 @@ public:
|
||||
{
|
||||
};
|
||||
|
||||
const char *what() const throw () override
|
||||
const char * what() const throw () override
|
||||
{
|
||||
return msg.c_str();
|
||||
}
|
||||
};
|
||||
|
||||
class goalFulfilledException : public std::exception
|
||||
{
|
||||
std::string msg;
|
||||
|
||||
public:
|
||||
Goals::TSubgoal goal;
|
||||
|
||||
explicit goalFulfilledException(Goals::TSubgoal Goal) : goal(Goal)
|
||||
explicit goalFulfilledException(Goals::TSubgoal Goal)
|
||||
: goal(Goal)
|
||||
{
|
||||
msg = goal->name();
|
||||
}
|
||||
@@ -442,11 +452,10 @@ public:
|
||||
{
|
||||
};
|
||||
|
||||
const char *what() const throw () override
|
||||
const char * what() const throw () override
|
||||
{
|
||||
return msg.c_str();
|
||||
}
|
||||
};
|
||||
|
||||
void makePossibleUpgrades(const CArmedInstance *obj);
|
||||
|
||||
void makePossibleUpgrades(const CArmedInstance * obj);
|
||||
|
@@ -14,19 +14,19 @@
|
||||
#define strcpy_s(a, b, c) strncpy(a, c, b)
|
||||
#endif
|
||||
|
||||
static const char *g_cszAiName = "VCAI";
|
||||
static const char * g_cszAiName = "VCAI";
|
||||
|
||||
extern "C" DLL_EXPORT int GetGlobalAiVersion()
|
||||
{
|
||||
return AI_INTERFACE_VER;
|
||||
}
|
||||
|
||||
extern "C" DLL_EXPORT void GetAiName(char* name)
|
||||
extern "C" DLL_EXPORT void GetAiName(char * name)
|
||||
{
|
||||
strcpy_s(name, strlen(g_cszAiName) + 1, g_cszAiName);
|
||||
}
|
||||
|
||||
extern "C" DLL_EXPORT void GetNewAI(std::shared_ptr<CGlobalAI> &out)
|
||||
extern "C" DLL_EXPORT void GetNewAI(std::shared_ptr<CGlobalAI> & out)
|
||||
{
|
||||
out = std::make_shared<VCAI>();
|
||||
}
|
||||
|
Reference in New Issue
Block a user