1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-04-25 12:14:46 +02:00

More work on VCAI Goals, still derived functions are not called :/

This commit is contained in:
DjWarmonger 2013-11-23 12:30:10 +00:00
parent 3e4407593f
commit e6bb39d3a4
4 changed files with 70 additions and 62 deletions

View File

@ -128,8 +128,10 @@ public:
tile = int3(-1, -1, -1); tile = int3(-1, -1, -1);
town = nullptr; town = nullptr;
} }
//virtual TSubgoal whatToDoToAchieve() override;
OSETTER(bool, isElementar) OSETTER(bool, isElementar)
OSETTER(bool, isAbstract) //FIXME: find out why this setter does not compile? OSETTER(bool, isAbstract)
OSETTER(bool, priority) OSETTER(bool, priority)
OSETTER(int, value) OSETTER(int, value)
OSETTER(int, resID) OSETTER(int, resID)
@ -143,6 +145,10 @@ public:
{ {
return make_shared<CGoal<T>> (setisElementar(true)); return make_shared<CGoal<T>> (setisElementar(true));
} }
template <typename Handler> void serialize(Handler &h, const int version)
{
h & static_cast<AbstractGoal&>(*this);
}
}; };
//There seems to be some ambiguity on these two, template function keeps form consitent //There seems to be some ambiguity on these two, template function keeps form consitent

View File

@ -1,5 +1,6 @@
#include "StdInc.h" #include "StdInc.h"
#include "VCAI.h" #include "VCAI.h"
#include "Goals.h"
#include "../../lib/UnlockGuard.h" #include "../../lib/UnlockGuard.h"
#include "../../lib/CObjectHandler.h" #include "../../lib/CObjectHandler.h"
#include "../../lib/CConfigHandler.h" #include "../../lib/CConfigHandler.h"
@ -713,12 +714,12 @@ void VCAI::makeTurnInternal()
logAi->errorStream() << "Error: there is wrong object on list for hero " << hero.first->name; logAi->errorStream() << "Error: there is wrong object on list for hero " << hero.first->name;
continue; continue;
} }
striveToGoal (Goals::VisitTile(obj->visitablePos()).sethero(hero.first)); striveToGoal (sptr(Goals::VisitTile(obj->visitablePos()).sethero(hero.first)));
} }
} }
//now try to win //now try to win
striveToGoal(Goals::Win()); striveToGoal(sptr(Goals::Win()));
//finally, continue our abstract long-term goals //finally, continue our abstract long-term goals
@ -740,7 +741,7 @@ void VCAI::makeTurnInternal()
if (it->first && it->first->tempOwner == playerID && vstd::contains(lockedHeroes, it->first)) //make sure hero still has his goal if (it->first && it->first->tempOwner == playerID && vstd::contains(lockedHeroes, it->first)) //make sure hero still has his goal
{ {
cb->setSelection(*it->first); cb->setSelection(*it->first);
striveToGoal (it->second); striveToGoal (make_shared<Goals::AbstractGoal>(it->second));
} }
safeCopy.erase(it); safeCopy.erase(it);
} }
@ -751,7 +752,7 @@ void VCAI::makeTurnInternal()
striveToQuest (quest); striveToQuest (quest);
} }
striveToGoal(Goals::Build()); //TODO: smarter building management striveToGoal(sptr(Goals::Build())); //TODO: smarter building management
} }
catch(boost::thread_interrupted &e) catch(boost::thread_interrupted &e)
{ {
@ -1156,7 +1157,7 @@ void VCAI::wander(HeroPtr h)
const CGTownInstance *t = townsNotReachable.back(); const CGTownInstance *t = townsNotReachable.back();
logAi->debugStream() << boost::format("%s can't reach any town, we'll try to make our way to %s at %s") % h->name % t->name % t->visitablePos(); logAi->debugStream() << boost::format("%s can't reach any town, we'll try to make our way to %s at %s") % h->name % t->name % t->visitablePos();
int3 pos1 = h->pos; int3 pos1 = h->pos;
striveToGoal(Goals::VisitTile(t->visitablePos()).sethero(h)); striveToGoal(sptr(Goals::VisitTile(t->visitablePos()).sethero(h)));
if (pos1 == h->pos && h == primaryHero()) //hero can't move if (pos1 == h->pos && h == primaryHero()) //hero can't move
{ {
if(cb->getResourceAmount(Res::GOLD) >= HERO_GOLD_COST && cb->getHeroesInfo().size() < ALLOWED_ROAMING_HEROES && cb->getAvailableHeroes(t).size()) if(cb->getResourceAmount(Res::GOLD) >= HERO_GOLD_COST && cb->getHeroesInfo().size() < ALLOWED_ROAMING_HEROES && cb->getAvailableHeroes(t).size())
@ -1687,18 +1688,19 @@ bool VCAI::fulfillsGoal (Goals::AbstractGoal &goal, const Goals::AbstractGoal &m
return fulfillsGoal (goal, const_cast<Goals::AbstractGoal&>(mainGoal)); return fulfillsGoal (goal, const_cast<Goals::AbstractGoal&>(mainGoal));
} }
void VCAI::striveToGoal(const Goals::AbstractGoal &ultimateGoal) void VCAI::striveToGoal(Goals::TSubgoal ultimateGoal)
{ {
if (ultimateGoal.invalid()) if (ultimateGoal->invalid())
return; return;
std::shared_ptr<Goals::AbstractGoal> abstractGoal = make_shared<Goals::AbstractGoal>(Goals::Invalid()); Goals::TSubgoal abstractGoal = sptr(Goals::Invalid());
while(1) while(1)
{ {
std::shared_ptr<Goals::AbstractGoal> goal = make_shared<Goals::AbstractGoal>(ultimateGoal); //FIXME: preserve subclass of goal Goals::TSubgoal goal = ultimateGoal; //FIXME: preserve subclass of goal
logAi->debugStream() << boost::format("Striving to goal of type %s") % ultimateGoal.name(); logAi->debugStream() << boost::format("Striving to goal of type %s") % ultimateGoal->name();
int maxGoals = 100; //preventing deadlock for mutually dependent goals, FIXME: do not try to realize goal when loop didn't suceed int maxGoals = 100; //preventing deadlock for mutually dependent goals
//FIXME: do not try to realize goal when loop didn't suceed
while(!goal->isElementar && !goal->isAbstract && maxGoals) while(!goal->isElementar && !goal->isAbstract && maxGoals)
{ {
logAi->debugStream() << boost::format("Considering goal %s") % goal->name(); logAi->debugStream() << boost::format("Considering goal %s") % goal->name();
@ -1757,12 +1759,12 @@ void VCAI::striveToGoal(const Goals::AbstractGoal &ultimateGoal)
catch(goalFulfilledException &e) catch(goalFulfilledException &e)
{ {
completeGoal (*goal); completeGoal (*goal);
if (fulfillsGoal (*goal, ultimateGoal) || maxGoals > 98) //completed goal was main goal //TODO: find better condition if (fulfillsGoal (*goal, *ultimateGoal.get()) || maxGoals > 98) //completed goal was main goal //TODO: find better condition
return; return;
} }
catch(std::exception &e) catch(std::exception &e)
{ {
logAi->debugStream() << boost::format("Failed to realize subgoal of type %s (greater goal type was %s), I will stop.") % goal->name() % ultimateGoal.name(); logAi->debugStream() << boost::format("Failed to realize subgoal of type %s (greater goal type was %s), I will stop.") % goal->name() % ultimateGoal->name();
logAi->debugStream() << boost::format("The error message was: %s") % e.what(); logAi->debugStream() << boost::format("The error message was: %s") % e.what();
break; break;
} }
@ -1816,7 +1818,7 @@ void VCAI::striveToGoal(const Goals::AbstractGoal &ultimateGoal)
} }
catch(std::exception &e) catch(std::exception &e)
{ {
logAi->debugStream() << boost::format("Failed to realize subgoal of type %s (greater goal type was %s), I will stop.") % goal->name() % ultimateGoal.name(); logAi->debugStream() << boost::format("Failed to realize subgoal of type %s (greater goal type was %s), I will stop.") % goal->name() % ultimateGoal->name();
logAi->debugStream() << boost::format("The error message was: %s") % e.what(); logAi->debugStream() << boost::format("The error message was: %s") % e.what();
break; break;
} }
@ -1841,13 +1843,13 @@ void VCAI::striveToQuest (const QuestInfo &q)
{ {
if (q.quest->checkQuest(hero)) if (q.quest->checkQuest(hero))
{ {
striveToGoal (Goals::GetObj(q.obj->id.getNum()).sethero(hero)); striveToGoal (sptr(Goals::GetObj(q.obj->id.getNum()).sethero(hero)));
return; return;
} }
} }
for (auto art : q.quest->m5arts) for (auto art : q.quest->m5arts)
{ {
striveToGoal (Goals::GetArtOfType(art)); //TODO: transport? striveToGoal (sptr(Goals::GetArtOfType(art))); //TODO: transport?
} }
break; break;
} }
@ -1858,11 +1860,11 @@ void VCAI::striveToQuest (const QuestInfo &q)
{ {
if (q.quest->checkQuest(hero)) if (q.quest->checkQuest(hero))
{ {
striveToGoal (Goals::GetObj(q.obj->id.getNum()).sethero(hero)); striveToGoal (sptr(Goals::GetObj(q.obj->id.getNum()).sethero(hero)));
return; return;
} }
} }
striveToGoal (Goals::FindObj(Obj::PRISON)); //rule of a thumb - quest heroes usually are locked in prisons striveToGoal (sptr(Goals::FindObj(Obj::PRISON))); //rule of a thumb - quest heroes usually are locked in prisons
//BNLOG ("Don't know how to recruit hero with id %d\n", q.quest->m13489val); //BNLOG ("Don't know how to recruit hero with id %d\n", q.quest->m13489val);
break; break;
} }
@ -1872,13 +1874,13 @@ void VCAI::striveToQuest (const QuestInfo &q)
{ {
if (q.quest->checkQuest(hero)) //veyr bad info - stacks can be split between multiple heroes :( if (q.quest->checkQuest(hero)) //veyr bad info - stacks can be split between multiple heroes :(
{ {
striveToGoal (Goals::GetObj(q.obj->id.getNum()).sethero(hero)); striveToGoal (sptr(Goals::GetObj(q.obj->id.getNum()).sethero(hero)));
return; return;
} }
} }
for (auto creature : q.quest->m6creatures) for (auto creature : q.quest->m6creatures)
{ {
striveToGoal (Goals::GatherTroops(creature.type->idNumber, creature.count)); striveToGoal (sptr(Goals::GatherTroops(creature.type->idNumber, creature.count)));
} }
//TODO: exchange armies... oh my //TODO: exchange armies... oh my
//BNLOG ("Don't know how to recruit %d of %s\n", (int)(creature.count) % creature.type->namePl); //BNLOG ("Don't know how to recruit %d of %s\n", (int)(creature.count) % creature.type->namePl);
@ -1890,19 +1892,19 @@ void VCAI::striveToQuest (const QuestInfo &q)
{ {
if (q.quest->checkQuest(heroes.front())) //it doesn't matter which hero it is if (q.quest->checkQuest(heroes.front())) //it doesn't matter which hero it is
{ {
striveToGoal (Goals::VisitTile(q.tile)); striveToGoal (sptr(Goals::VisitTile(q.tile)));
} }
else else
{ {
for (int i = 0; i < q.quest->m7resources.size(); ++i) for (int i = 0; i < q.quest->m7resources.size(); ++i)
{ {
if (q.quest->m7resources[i]) if (q.quest->m7resources[i])
striveToGoal (Goals::CollectRes(i, q.quest->m7resources[i])); striveToGoal (sptr(Goals::CollectRes(i, q.quest->m7resources[i])));
} }
} }
} }
else else
striveToGoal (Goals::RecruitHero()); //FIXME: checkQuest requires any hero belonging to player :( striveToGoal (sptr(Goals::RecruitHero())); //FIXME: checkQuest requires any hero belonging to player :(
break; break;
} }
case CQuest::MISSION_KILL_HERO: case CQuest::MISSION_KILL_HERO:
@ -1910,9 +1912,9 @@ void VCAI::striveToQuest (const QuestInfo &q)
{ {
auto obj = cb->getObjByQuestIdentifier(q.quest->m13489val); auto obj = cb->getObjByQuestIdentifier(q.quest->m13489val);
if (obj) if (obj)
striveToGoal (Goals::GetObj(obj->id.getNum())); striveToGoal (sptr(Goals::GetObj(obj->id.getNum())));
else else
striveToGoal (Goals::VisitTile(q.tile)); //visit seer hut striveToGoal (sptr(Goals::VisitTile(q.tile))); //visit seer hut
break; break;
} }
case CQuest::MISSION_PRIMARY_STAT: case CQuest::MISSION_PRIMARY_STAT:
@ -1922,7 +1924,7 @@ void VCAI::striveToQuest (const QuestInfo &q)
{ {
if (q.quest->checkQuest(hero)) if (q.quest->checkQuest(hero))
{ {
striveToGoal (Goals::GetObj(q.obj->id.getNum()).sethero(hero)); striveToGoal (sptr(Goals::GetObj(q.obj->id.getNum()).sethero(hero)));
return; return;
} }
} }
@ -1939,7 +1941,7 @@ void VCAI::striveToQuest (const QuestInfo &q)
{ {
if (q.quest->checkQuest(hero)) if (q.quest->checkQuest(hero))
{ {
striveToGoal (Goals::VisitTile(q.tile).sethero(hero)); //TODO: causes infinite loop :/ striveToGoal (sptr(Goals::VisitTile(q.tile).sethero(hero))); //TODO: causes infinite loop :/
return; return;
} }
} }
@ -1954,7 +1956,7 @@ void VCAI::striveToQuest (const QuestInfo &q)
} }
case CQuest::MISSION_KEYMASTER: case CQuest::MISSION_KEYMASTER:
{ {
striveToGoal (Goals::FindObj(Obj::KEYMASTER, q.obj->subID)); striveToGoal (sptr(Goals::FindObj(Obj::KEYMASTER, q.obj->subID)));
break; break;
} }
} }

View File

@ -231,7 +231,7 @@ public:
void performTypicalActions(); void performTypicalActions();
void buildArmyIn(const CGTownInstance * t); void buildArmyIn(const CGTownInstance * t);
void striveToGoal(const Goals::AbstractGoal & ultimateGoal); void striveToGoal(Goals::TSubgoal ultimateGoal);
void endTurn(); void endTurn();
void wander(HeroPtr h); void wander(HeroPtr h);
void setGoal(HeroPtr h, const Goals::AbstractGoal &goal); void setGoal(HeroPtr h, const Goals::AbstractGoal &goal);

View File

@ -2112,13 +2112,13 @@ int CGTownInstance::creatureDwellingLevel(int dwelling) const
if (!hasBuilt(BuildingID(BuildingID::DWELL_FIRST+dwelling+i*GameConstants::CREATURES_PER_TOWN))) if (!hasBuilt(BuildingID(BuildingID::DWELL_FIRST+dwelling+i*GameConstants::CREATURES_PER_TOWN)))
return i-1; return i-1;
} }
} }
int CGTownInstance::getHordeLevel(const int & HID) const//HID - 0 or 1; returns creature level or -1 if that horde structure is not present int CGTownInstance::getHordeLevel(const int & HID) const//HID - 0 or 1; returns creature level or -1 if that horde structure is not present
{ {
return town->hordeLvl.at(HID); return town->hordeLvl.at(HID);
} }
int CGTownInstance::creatureGrowth(const int & level) const int CGTownInstance::creatureGrowth(const int & level) const
{ {
return getGrowthInfo(level).totalGrowth(); return getGrowthInfo(level).totalGrowth();
} }
@ -2139,17 +2139,17 @@ GrowthInfo CGTownInstance::getGrowthInfo(int level) const
if (hasBuilt(BuildingID::CASTLE)) if (hasBuilt(BuildingID::CASTLE))
ret.entries.push_back(GrowthInfo::Entry(subID, BuildingID::CASTLE, castleBonus = base)); ret.entries.push_back(GrowthInfo::Entry(subID, BuildingID::CASTLE, castleBonus = base));
else if (hasBuilt(BuildingID::CITADEL)) else if (hasBuilt(BuildingID::CITADEL))
ret.entries.push_back(GrowthInfo::Entry(subID, BuildingID::CITADEL, castleBonus = base / 2)); ret.entries.push_back(GrowthInfo::Entry(subID, BuildingID::CITADEL, castleBonus = base / 2));
if(town->hordeLvl.at(0) == level)//horde 1 if(town->hordeLvl.at(0) == level)//horde 1
if(hasBuilt(BuildingID::HORDE_1)) if(hasBuilt(BuildingID::HORDE_1))
ret.entries.push_back(GrowthInfo::Entry(subID, BuildingID::HORDE_1, creature->hordeGrowth)); ret.entries.push_back(GrowthInfo::Entry(subID, BuildingID::HORDE_1, creature->hordeGrowth));
if(town->hordeLvl.at(1) == level)//horde 2 if(town->hordeLvl.at(1) == level)//horde 2
if(hasBuilt(BuildingID::HORDE_2)) if(hasBuilt(BuildingID::HORDE_2))
ret.entries.push_back(GrowthInfo::Entry(subID, BuildingID::HORDE_2, creature->hordeGrowth)); ret.entries.push_back(GrowthInfo::Entry(subID, BuildingID::HORDE_2, creature->hordeGrowth));
int dwellingBonus = 0; int dwellingBonus = 0;
if(const PlayerState *p = cb->getPlayer(tempOwner, false)) if(const PlayerState *p = cb->getPlayer(tempOwner, false))
{ {
@ -2617,13 +2617,13 @@ bool CGTownInstance::addBonusIfBuilt(BuildingID building, Bonus::BonusType type,
bool CGTownInstance::addBonusIfBuilt(BuildingID building, Bonus::BonusType type, int val, TPropagatorPtr & prop, int subtype /*= -1*/) bool CGTownInstance::addBonusIfBuilt(BuildingID building, Bonus::BonusType type, int val, TPropagatorPtr & prop, int subtype /*= -1*/)
{ {
if(hasBuilt(building)) if(hasBuilt(building))
{ {
std::ostringstream descr; std::ostringstream descr;
descr << town->buildings.at(building)->Name() << " "; descr << town->buildings.at(building)->Name() << " ";
if(val > 0) if(val > 0)
descr << "+"; descr << "+";
else if(val < 0) else if(val < 0)
descr << "-"; descr << "-";
descr << val; descr << val;
@ -2692,13 +2692,13 @@ bool CGTownInstance::armedGarrison() const
int CGTownInstance::getTownLevel() const int CGTownInstance::getTownLevel() const
{ {
// count all buildings that are not upgrades // count all buildings that are not upgrades
return boost::range::count_if(builtBuildings, [&](const BuildingID & build) return boost::range::count_if(builtBuildings, [&](const BuildingID & build)
{ {
return town->buildings.at(build) && town->buildings.at(build)->upgrade == -1; return town->buildings.at(build) && town->buildings.at(build)->upgrade == -1;
}); });
} }
CBonusSystemNode * CGTownInstance::whatShouldBeAttached() CBonusSystemNode * CGTownInstance::whatShouldBeAttached()
{ {
return &townAndVis; return &townAndVis;