mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-24 22:14:36 +02:00
- Implemented serialization of Goals. Loaded games work, at least.
- Attempts to add Subterranean Gates to SectorMap - Extensive use of ClearWayTo goal.
This commit is contained in:
parent
8a9f2781c2
commit
b0b0249524
@ -480,6 +480,32 @@ float FuzzyHelper::evaluate (Goals::GatherArmy & g)
|
||||
float army = g.hero->getArmyStrength();
|
||||
return g.value / std::max(g.value - army, 1000.0f);
|
||||
}
|
||||
|
||||
float FuzzyHelper::evaluate (Goals::ClearWayTo & g)
|
||||
{
|
||||
if (!g.hero.h)
|
||||
throw cannotFulfillGoalException("ClearWayTo called without hero!");
|
||||
|
||||
SectorMap sm(g.hero);
|
||||
int3 t = sm.firstTileToGet(g.hero, g.tile);
|
||||
|
||||
if (t.valid())
|
||||
{
|
||||
if (isSafeToVisit(g.hero, t))
|
||||
{
|
||||
g.setpriority(Goals::VisitTile(g.tile).sethero(g.hero).setisAbstract(g.isAbstract).accept(this));
|
||||
}
|
||||
else
|
||||
{
|
||||
g.setpriority (Goals::GatherArmy(evaluateDanger(t, g.hero.h)*SAFE_ATTACK_CONSTANT).
|
||||
sethero(g.hero).setisAbstract(true).accept(this));
|
||||
}
|
||||
return g.priority;
|
||||
}
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
float FuzzyHelper::evaluate (Goals::BuildThis & g)
|
||||
{
|
||||
return 1;
|
||||
|
@ -67,6 +67,7 @@ public:
|
||||
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);
|
||||
|
@ -452,16 +452,28 @@ TSubgoal ClearWayTo::whatToDoToAchieve()
|
||||
TGoalVec ClearWayTo::getAllPossibleSubgoals()
|
||||
{
|
||||
TGoalVec ret;
|
||||
for (auto h : cb->getHeroesInfo())
|
||||
|
||||
std::vector<const CGHeroInstance *> heroes;
|
||||
|
||||
if (hero)
|
||||
heroes.push_back(hero.h);
|
||||
else
|
||||
{
|
||||
if ((hero && hero->visitablePos() == tile && hero == *h) || //we can't free the way ourselves
|
||||
h->visitablePos() == tile) //we are already on that tile! what does it mean?
|
||||
continue;
|
||||
heroes = cb->getHeroesInfo();
|
||||
}
|
||||
|
||||
for (auto h : heroes)
|
||||
{
|
||||
//TODO: handle clearing way to allied heroes that are blocked
|
||||
//if ((hero && hero->visitablePos() == tile && hero == *h) || //we can't free the way ourselves
|
||||
// h->visitablePos() == tile) //we are already on that tile! what does it mean?
|
||||
// continue;
|
||||
|
||||
//if our hero is trapped, make sure we request clearing the way from OUR perspective
|
||||
|
||||
SectorMap sm(h);
|
||||
|
||||
int3 tileToHit = sm.firstTileToGet(hero ? hero : h, tile);
|
||||
//if our hero is trapped, make sure we request clearing the way from OUR perspective
|
||||
int3 tileToHit = sm.firstTileToGet(h, tile);
|
||||
if (!tileToHit.valid())
|
||||
continue;
|
||||
|
||||
@ -471,10 +483,13 @@ TGoalVec ClearWayTo::getAllPossibleSubgoals()
|
||||
}
|
||||
|
||||
auto topObj = cb->getTopObj(tileToHit);
|
||||
if(topObj)
|
||||
if (topObj)
|
||||
{
|
||||
if (vstd::contains(ai->reservedObjs, topObj) && !vstd::contains(ai->reservedHeroesMap[h], topObj))
|
||||
continue; //do not capure object reserved by other hero
|
||||
|
||||
if (topObj->ID == Obj::HERO && cb->getPlayerRelations(h->tempOwner, topObj->tempOwner) != PlayerRelations::ENEMIES)
|
||||
if (topObj != hero.get(true)) //the hero we wnat to free
|
||||
if (topObj != hero.get(true)) //the hero we want to free
|
||||
logAi->errorStream() << boost::format("%s stands in the way of %s") % topObj->getHoverText() % h->getHoverText();
|
||||
if (topObj->ID == Obj::QUEST_GUARD || topObj->ID == Obj::BORDERGUARD)
|
||||
{
|
||||
@ -482,6 +497,7 @@ TGoalVec ClearWayTo::getAllPossibleSubgoals()
|
||||
{
|
||||
//do NOT use VISIT_TILE, as tile with quets guard can't be visited
|
||||
ret.push_back (sptr (Goals::GetObj(topObj->id.getNum()).sethero(h)));
|
||||
continue; //do not try to visit tile or gather army
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -490,8 +506,16 @@ TGoalVec ClearWayTo::getAllPossibleSubgoals()
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
if (isSafeToVisit(h, tileToHit)) //this makes sense only if tile is guarded, but there i no quest object
|
||||
{
|
||||
ret.push_back (sptr (Goals::VisitTile(tileToHit).sethero(h)));
|
||||
}
|
||||
else
|
||||
{
|
||||
ret.push_back (sptr (Goals::GatherArmy(evaluateDanger(tileToHit, h)*SAFE_ATTACK_CONSTANT).
|
||||
sethero(h).setisAbstract(true)));
|
||||
}
|
||||
}
|
||||
if (ai->canRecruitAnyHero())
|
||||
ret.push_back (sptr (Goals::RecruitHero()));
|
||||
@ -563,10 +587,12 @@ TGoalVec Explore::getAllPossibleSubgoals()
|
||||
for (auto h : heroes)
|
||||
{
|
||||
SectorMap sm(h);
|
||||
|
||||
for (auto obj : objs) //double loop, performance risk?
|
||||
{
|
||||
auto t = sm.firstTileToGet(h, obj->visitablePos()); //we assume that no more than one tile on the way is guarded
|
||||
ai->whatToDoToReachTile(h, t, ret);
|
||||
if (ai->canReachTile(h, t))
|
||||
ret.push_back (sptr(Goals::ClearWayTo(obj->visitablePos(), h).setisAbstract(true)));
|
||||
}
|
||||
|
||||
int3 t = whereToExplore(h);
|
||||
@ -577,33 +603,14 @@ TGoalVec Explore::getAllPossibleSubgoals()
|
||||
else if (hero.h == h || (!hero && h == ai->primaryHero().h)) //check this only ONCE, high cost
|
||||
{
|
||||
t = ai->explorationDesperate(h);
|
||||
ai->whatToDoToReachTile(h, t, ret);
|
||||
if (t.valid()) //don't waste time if we are completely blocked
|
||||
ret.push_back (sptr(Goals::ClearWayTo(t, h).setisAbstract(true)));
|
||||
}
|
||||
}
|
||||
//we either don't have hero yet or none of heroes can explore
|
||||
if ((!hero || ret.empty()) && ai->canRecruitAnyHero())
|
||||
ret.push_back (sptr(Goals::RecruitHero()));
|
||||
|
||||
//if (ret.empty())
|
||||
//{
|
||||
// for (auto h : heroes) //this is costly function, use only when there is no other way
|
||||
// {
|
||||
// auto t = ai->explorationDesperate (h); //we assume that no more than one tile on the way is guarded
|
||||
// if (t.valid())
|
||||
// {
|
||||
// if (isSafeToVisit(h, t))
|
||||
// {
|
||||
// ret.push_back (sptr (Goals::VisitTile(t).sethero(h)));
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// ret.push_back (sptr (Goals::GatherArmy(evaluateDanger(t, h)*SAFE_ATTACK_CONSTANT).
|
||||
// sethero(h).setisAbstract(true)));
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
|
||||
if (ret.empty())
|
||||
{
|
||||
throw goalFulfilledException (sptr(Goals::Explore().sethero(hero)));
|
||||
@ -886,7 +893,8 @@ TGoalVec Conquer::getAllPossibleSubgoals()
|
||||
for (auto obj : ourObjs) //double loop, performance risk?
|
||||
{
|
||||
auto t = sm.firstTileToGet(h, obj->visitablePos()); //we assume that no more than one tile on the way is guarded
|
||||
ai->whatToDoToReachTile (h, t, ret);
|
||||
if (ai->canReachTile(h, t))
|
||||
ret.push_back (sptr(Goals::ClearWayTo(obj->visitablePos(), h).setisAbstract(true)));
|
||||
}
|
||||
}
|
||||
if (!objs.empty() && ai->canRecruitAnyHero()) //probably no point to recruit hero if we see no objects to capture
|
||||
|
@ -193,7 +193,7 @@ class NotLose : public CGoal<NotLose>
|
||||
public:
|
||||
NotLose() : CGoal (Goals::DO_NOT_LOSE) {priority = 100;};
|
||||
TGoalVec getAllPossibleSubgoals() override {return TGoalVec();};
|
||||
TSubgoal whatToDoToAchieve() override;
|
||||
//TSubgoal whatToDoToAchieve() override;
|
||||
};
|
||||
class Conquer : public CGoal<Conquer>
|
||||
{
|
||||
@ -221,9 +221,9 @@ class Explore : public CGoal<Explore>
|
||||
};
|
||||
class GatherArmy : public CGoal<GatherArmy>
|
||||
{
|
||||
private:
|
||||
GatherArmy() : CGoal (Goals::GATHER_ARMY){};
|
||||
public:
|
||||
GatherArmy() : CGoal (Goals::GATHER_ARMY){};
|
||||
|
||||
GatherArmy(int val) : CGoal (Goals::GATHER_ARMY){value = val; priority = 2.5;};
|
||||
TGoalVec getAllPossibleSubgoals() override;
|
||||
TSubgoal whatToDoToAchieve() override;
|
||||
@ -234,7 +234,7 @@ class BoostHero : public CGoal<BoostHero>
|
||||
public:
|
||||
BoostHero() : CGoal (Goals::INVALID){priority = -1e10;}; //TODO
|
||||
TGoalVec getAllPossibleSubgoals() override {return TGoalVec();};
|
||||
TSubgoal whatToDoToAchieve() override;
|
||||
//TSubgoal whatToDoToAchieve() override {return sptr(Invalid());};
|
||||
};
|
||||
class RecruitHero : public CGoal<RecruitHero>
|
||||
{
|
||||
@ -245,9 +245,9 @@ class RecruitHero : public CGoal<RecruitHero>
|
||||
};
|
||||
class BuildThis : public CGoal<BuildThis>
|
||||
{
|
||||
private:
|
||||
BuildThis() : CGoal (Goals::BUILD_STRUCTURE){};
|
||||
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();};
|
||||
@ -255,27 +255,27 @@ public:
|
||||
};
|
||||
class CollectRes : public CGoal<CollectRes>
|
||||
{
|
||||
private:
|
||||
public:
|
||||
CollectRes() : CGoal (Goals::COLLECT_RES){};
|
||||
public:
|
||||
|
||||
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>
|
||||
{
|
||||
private:
|
||||
GatherTroops() : CGoal (Goals::GATHER_TROOPS){priority = 2;};
|
||||
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();};
|
||||
TSubgoal whatToDoToAchieve() override;
|
||||
};
|
||||
class GetObj : public CGoal<GetObj>
|
||||
{
|
||||
private:
|
||||
GetObj() {}; // empty constructor not allowed
|
||||
public:
|
||||
GetObj() {}; // empty constructor not allowed
|
||||
|
||||
GetObj(int Objid) : CGoal(Goals::GET_OBJ) {objid = Objid; priority = 3;};
|
||||
TGoalVec getAllPossibleSubgoals() override {return TGoalVec();};
|
||||
TSubgoal whatToDoToAchieve() override;
|
||||
@ -285,9 +285,9 @@ public:
|
||||
};
|
||||
class FindObj : public CGoal<FindObj>
|
||||
{
|
||||
private:
|
||||
FindObj() {}; // empty constructor not allowed
|
||||
public:
|
||||
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();};
|
||||
@ -295,9 +295,9 @@ public:
|
||||
};
|
||||
class VisitHero : public CGoal<VisitHero>
|
||||
{
|
||||
private:
|
||||
VisitHero() : CGoal (Goals::VISIT_HERO){};
|
||||
public:
|
||||
VisitHero() : CGoal (Goals::VISIT_HERO){};
|
||||
|
||||
VisitHero(int hid) : CGoal (Goals::VISIT_HERO){objid = hid; priority = 4;};
|
||||
TGoalVec getAllPossibleSubgoals() override {return TGoalVec();};
|
||||
TSubgoal whatToDoToAchieve() override;
|
||||
@ -307,9 +307,9 @@ public:
|
||||
};
|
||||
class GetArtOfType : public CGoal<GetArtOfType>
|
||||
{
|
||||
private:
|
||||
GetArtOfType() : CGoal (Goals::GET_ART_TYPE){};
|
||||
public:
|
||||
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;
|
||||
@ -317,9 +317,9 @@ public:
|
||||
class VisitTile : public CGoal<VisitTile>
|
||||
//tile, in conjunction with hero elementar; assumes tile is reachable
|
||||
{
|
||||
private:
|
||||
VisitTile() {}; // empty constructor not allowed
|
||||
public:
|
||||
VisitTile() {}; // empty constructor not allowed
|
||||
|
||||
VisitTile(int3 Tile) : CGoal (Goals::VISIT_TILE) {tile = Tile; priority = 5;};
|
||||
TGoalVec getAllPossibleSubgoals() override;
|
||||
TSubgoal whatToDoToAchieve() override;
|
||||
@ -329,7 +329,10 @@ public:
|
||||
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;};
|
||||
TGoalVec getAllPossibleSubgoals() override;
|
||||
TSubgoal whatToDoToAchieve() override;
|
||||
bool operator== (ClearWayTo &g) {return g.tile == tile;}
|
||||
@ -337,9 +340,9 @@ public:
|
||||
class DigAtTile : public CGoal<DigAtTile>
|
||||
//elementar with hero on tile
|
||||
{
|
||||
private:
|
||||
DigAtTile() : CGoal (Goals::DIG_AT_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();};
|
||||
TSubgoal whatToDoToAchieve() override;
|
||||
@ -351,9 +354,11 @@ 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;
|
||||
//TSubgoal whatToDoToAchieve() override {return sptr(Invalid());};
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -598,6 +598,8 @@ void VCAI::saveGame(COSer<CSaveFile> &h, const int version)
|
||||
LOG_TRACE_PARAMS(logAi, "version '%i'", version);
|
||||
NET_EVENT_HANDLER;
|
||||
validateVisitableObjs();
|
||||
|
||||
registerGoals(h);
|
||||
CAdventureAI::saveGame(h, version);
|
||||
serializeInternal(h, version);
|
||||
}
|
||||
@ -606,6 +608,8 @@ void VCAI::loadGame(CISer<CLoadFile> &h, const int version)
|
||||
{
|
||||
LOG_TRACE_PARAMS(logAi, "version '%i'", version);
|
||||
NET_EVENT_HANDLER;
|
||||
|
||||
registerGoals(h);
|
||||
CAdventureAI::loadGame(h, version);
|
||||
serializeInternal(h, version);
|
||||
}
|
||||
@ -1215,24 +1219,18 @@ std::vector<const CGObjectInstance *> VCAI::getPossibleDestinations(HeroPtr h)
|
||||
return possibleDestinations;
|
||||
}
|
||||
|
||||
void VCAI::whatToDoToReachTile (const CGHeroInstance * h, int3 t, Goals::TGoalVec& vec)
|
||||
///TODO: possibly merge with Goals::ClearWayTo
|
||||
bool VCAI::canReachTile (const CGHeroInstance * h, int3 t)
|
||||
{
|
||||
if (t.valid())
|
||||
{
|
||||
auto obj = cb->getTopObj(t);
|
||||
if (obj && vstd::contains(ai->reservedObjs, obj) && !vstd::contains(reservedHeroesMap[h], obj))
|
||||
return; //do not capture object reserved by another hero
|
||||
if (isSafeToVisit(h, t))
|
||||
{
|
||||
vec.push_back (sptr (Goals::VisitTile(t).sethero(h)));
|
||||
}
|
||||
return false; //do not capture object reserved by another hero
|
||||
else
|
||||
{
|
||||
vec.push_back (sptr (Goals::GatherArmy(evaluateDanger(t, h)*SAFE_ATTACK_CONSTANT).
|
||||
sethero(h).setisAbstract(true)));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
bool VCAI::canRecruitAnyHero (const CGTownInstance * t) const
|
||||
@ -2709,8 +2707,16 @@ void SectorMap::exploreNewSector(crint3 pos, int num)
|
||||
s.embarkmentPoints.push_back(neighPos);
|
||||
}
|
||||
});
|
||||
if(t->visitable && vstd::contains(ai->knownSubterraneanGates, t->visitableObjects.front()))
|
||||
toVisit.push(ai->knownSubterraneanGates[t->visitableObjects.front()]->visitablePos());
|
||||
|
||||
if(t->visitable)
|
||||
{
|
||||
auto obj = t->visitableObjects.front();
|
||||
if (vstd::contains(ai->knownSubterraneanGates, obj))
|
||||
{ //not really sure what does it do, but subtrranean gates do not make one sector
|
||||
toVisit.push(ai->knownSubterraneanGates[obj]->visitablePos());
|
||||
s.subterraneanGates.push_back (obj);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2893,7 +2899,20 @@ For ship construction etc, another function (goal?) is needed
|
||||
}
|
||||
}
|
||||
|
||||
//TODO consider other types of connections between sectors?
|
||||
for (auto gate : s->subterraneanGates)
|
||||
{
|
||||
auto gatePair = ai->knownSubterraneanGates.find(gate);
|
||||
if (gatePair != ai->knownSubterraneanGates.end())
|
||||
{
|
||||
//check the other side of gate
|
||||
Sector *neigh = &infoOnSectors[retreiveTile(gatePair->second->visitablePos())];
|
||||
if(!preds[neigh]) //if we didn't come into this sector yet
|
||||
{
|
||||
preds[neigh] = s; //it becomes our new target sector
|
||||
sq.push(neigh);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(!preds[dst])
|
||||
@ -3001,10 +3020,19 @@ For ship construction etc, another function (goal?) is needed
|
||||
//disembark
|
||||
return ret;
|
||||
}
|
||||
else
|
||||
else //use subterranean gates
|
||||
{
|
||||
auto firstGate = boost::find_if(src->subterraneanGates, [=](const CGObjectInstance * gate) -> bool
|
||||
{
|
||||
return retreiveTile(gate->visitablePos()) == sectorToReach->id;
|
||||
});
|
||||
|
||||
if(firstGate != src->subterraneanGates.end())
|
||||
{
|
||||
return (*firstGate)->visitablePos();
|
||||
}
|
||||
//TODO
|
||||
//transition between two land/water sectors. Monolith? Whirlpool? ...
|
||||
//Monolith? Whirlpool? ...
|
||||
return ret;
|
||||
//throw cannotFulfillGoalException("Land-land and water-water inter-sector transitions are not implemented!");
|
||||
}
|
||||
@ -3078,19 +3106,6 @@ void SectorMap::makeParentBFS(crint3 source)
|
||||
}
|
||||
}
|
||||
});
|
||||
//this code is unused, as tiles on both sides of game are different sectors
|
||||
|
||||
//const TerrainTile *t = cb->getTile(curPos);
|
||||
//if(t->topVisitableId() == Obj::SUBTERRANEAN_GATE)
|
||||
//{
|
||||
// //try finding the exit gate
|
||||
// auto it = ai->knownSubterraneanGates.find(t->topVisitableObj());
|
||||
// if (it != ai->knownSubterraneanGates.end())
|
||||
// {
|
||||
// const int3 outPos = it->second->visitablePos();
|
||||
// parent[outPos] = curPos; //TODO: is it only one tile?
|
||||
// }
|
||||
//}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -83,6 +83,7 @@ struct SectorMap
|
||||
int id;
|
||||
std::vector<int3> tiles;
|
||||
std::vector<int3> embarkmentPoints; //tiles of other sectors onto which we can (dis)embark
|
||||
std::vector<const CGObjectInstance *> subterraneanGates;
|
||||
bool water; //all tiles of sector are land or water
|
||||
Sector()
|
||||
{
|
||||
@ -180,7 +181,7 @@ public:
|
||||
int3 explorationBestNeighbour(int3 hpos, int radius, HeroPtr h);
|
||||
int3 explorationNewPoint(HeroPtr h);
|
||||
int3 explorationDesperate(HeroPtr h);
|
||||
void whatToDoToReachTile (const CGHeroInstance * h, int3 t, Goals::TGoalVec& vec);
|
||||
bool canReachTile (const CGHeroInstance * h, int3 t);
|
||||
void recruitHero();
|
||||
|
||||
virtual std::string getBattleAIName() const override;
|
||||
@ -312,6 +313,29 @@ public:
|
||||
//special function that can be called ONLY from game events handling thread and will send request ASAP
|
||||
void requestActionASAP(std::function<void()> whatToDo);
|
||||
|
||||
template <typename Handler> void registerGoals(Handler &h)
|
||||
{
|
||||
//h.registerType<Goals::AbstractGoal, Goals::BoostHero>();
|
||||
h.registerType<Goals::AbstractGoal, Goals::Build>();
|
||||
h.registerType<Goals::AbstractGoal, Goals::BuildThis>();
|
||||
//h.registerType<Goals::AbstractGoal, Goals::CIssueCommand>();
|
||||
h.registerType<Goals::AbstractGoal, Goals::ClearWayTo>();
|
||||
h.registerType<Goals::AbstractGoal, Goals::CollectRes>();
|
||||
h.registerType<Goals::AbstractGoal, Goals::Conquer>();
|
||||
h.registerType<Goals::AbstractGoal, Goals::DigAtTile>();
|
||||
h.registerType<Goals::AbstractGoal, Goals::Explore>();
|
||||
h.registerType<Goals::AbstractGoal, Goals::FindObj>();
|
||||
h.registerType<Goals::AbstractGoal, Goals::GatherArmy>();
|
||||
h.registerType<Goals::AbstractGoal, Goals::GatherTroops>();
|
||||
h.registerType<Goals::AbstractGoal, Goals::GetArtOfType>();
|
||||
h.registerType<Goals::AbstractGoal, Goals::GetObj>();
|
||||
h.registerType<Goals::AbstractGoal, Goals::Invalid>();
|
||||
//h.registerType<Goals::AbstractGoal, Goals::NotLose>();
|
||||
h.registerType<Goals::AbstractGoal, Goals::RecruitHero>();
|
||||
h.registerType<Goals::AbstractGoal, Goals::VisitHero>();
|
||||
h.registerType<Goals::AbstractGoal, Goals::VisitTile>();
|
||||
h.registerType<Goals::AbstractGoal, Goals::Win>();
|
||||
}
|
||||
|
||||
template <typename Handler> void serializeInternal(Handler &h, const int version)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user