1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-12-24 22:14:36 +02:00

- VCAI can now complete all types of Seer Hut Mission. GATHERTROOP victory condition should also work.

- Minor tweaks.
This commit is contained in:
DjWarmonger 2012-07-21 07:15:53 +00:00
parent 9207e4f4a4
commit 356e675a65
5 changed files with 92 additions and 13 deletions

View File

@ -606,6 +606,7 @@ void VCAI::heroVisit(const CGHeroInstance *visitor, const CGObjectInstance *visi
markObjectVisited (visitedObj);
remove_if_present(reservedObjs, visitedObj); //unreserve objects
remove_if_present(reservedHeroesMap[visitor], visitedObj);
completeGoal (CGoal(GET_OBJ).sethero(visitor)); //we don't need to visit in anymore
}
}
@ -2084,10 +2085,20 @@ void VCAI::striveToQuest (const QuestInfo &q)
MetaString ms;
q.quest->getRolloverText(ms, false);
BNLOG ("Trying to realize quest: %s", ms.toString());
auto heroes = cb->getHeroesInfo();
switch (q.quest->missionType)
{
case CQuest::MISSION_ART:
{
BOOST_FOREACH (auto hero, heroes) //TODO: remove duplicated code?
{
if (q.quest->checkQuest(hero))
{
striveToGoal (CGoal(GET_OBJ).setobjid(q.obj->id).sethero(hero));
return;
}
}
BOOST_FOREACH (auto art, q.quest->m5arts)
{
striveToGoal (CGoal(GET_ART_TYPE).setaid(art)); //TODO: transport?
@ -2097,33 +2108,49 @@ void VCAI::striveToQuest (const QuestInfo &q)
case CQuest::MISSION_HERO:
{
//striveToGoal (CGoal(RECRUIT_HERO));
auto heroes = cb->getHeroesInfo();
BOOST_FOREACH (auto hero, heroes)
{
if (q.quest->checkQuest(hero))
{
striveToGoal (CGoal(GET_OBJ).setobjid(q.obj->id).sethero(hero));
break;
return;
}
}
BNLOG ("Don't know how to recruit hero with id %d\n", q.quest->m13489val);
striveToGoal (CGoal(FIND_OBJ).setobjid(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);
break;
}
case CQuest::MISSION_ARMY:
{
BOOST_FOREACH (auto hero, heroes)
{
if (q.quest->checkQuest(hero)) //veyr bad info - stacks can be split between multiple heroes :(
{
striveToGoal (CGoal(GET_OBJ).setobjid(q.obj->id).sethero(hero));
return;
}
}
BOOST_FOREACH (auto creature, q.quest->m6creatures)
{
BNLOG ("Don't know how to recruit %d of %s\n", (int)(creature.count) % creature.type->namePl);
striveToGoal (CGoal(GATHER_TROOPS).setobjid(creature.type->idNumber).setvalue(creature.count));
}
//TODO: exchange armies... oh my
//BNLOG ("Don't know how to recruit %d of %s\n", (int)(creature.count) % creature.type->namePl);
break;
}
case CQuest::MISSION_RESOURCES:
{
for (int i = 0; i < q.quest->m7resources.size(); ++i)
if (q.quest->checkQuest(NULL))
{
if (q.quest->m7resources[i])
striveToGoal (CGoal(COLLECT_RES).setresID(i).setvalue(q.quest->m7resources[i]));
//TODO: visit object
striveToGoal (CGoal(VISIT_TILE).settile(q.tile));
}
else
{
for (int i = 0; i < q.quest->m7resources.size(); ++i)
{
if (q.quest->m7resources[i])
striveToGoal (CGoal(COLLECT_RES).setresID(i).setvalue(q.quest->m7resources[i]));
}
}
break;
}
@ -2145,7 +2172,7 @@ void VCAI::striveToQuest (const QuestInfo &q)
if (q.quest->checkQuest(hero))
{
striveToGoal (CGoal(GET_OBJ).setobjid(q.obj->id).sethero(hero));
break;
return;
}
}
for (int i = 0; i < q.quest->m2stats.size(); ++i)
@ -2161,8 +2188,8 @@ void VCAI::striveToQuest (const QuestInfo &q)
{
if (q.quest->checkQuest(hero))
{
striveToGoal (CGoal(GET_OBJ).setobjid(q.obj->id).sethero(hero));
break;
striveToGoal (CGoal(VISIT_TILE).settile(q.tile).sethero(hero)); //TODO: causes infinite loop :/
return;
}
}
BNLOG ("Don't know how to reach hero level %d\n", q.quest->m13489val);
@ -2651,6 +2678,7 @@ TSubgoal CGoal::whatToDoToAchieve()
//save?
break;
case EVictoryConditionType::GATHERTROOP:
return CGoal(GATHER_TROOPS).setobjid(vc.ID).setvalue(vc.count);
break;
case EVictoryConditionType::TAKEDWELLINGS:
break;
@ -2939,6 +2967,53 @@ TSubgoal CGoal::whatToDoToAchieve()
}
}
return CGoal(INVALID);
case GATHER_TROOPS:
{
std::vector<const CGDwelling *> dwellings;
BOOST_FOREACH(const CGTownInstance *t, cb->getTownsInfo())
{
auto creature = VLC->creh->creatures[objid];
if (t->subID == creature->faction) //TODO: how to force AI to build unupgraded creatures? :O
{
int bid = t->creatureDwelling(creature->level);
if (t->hasBuilt(bid)) //this assumes only creatures with dwellings are assigned to faction
{
dwellings.push_back(t);
}
else
{
return CGoal (BUILD_STRUCTURE).settown(t).setbid(bid);
}
}
}
BOOST_FOREACH (auto obj, ai->visitableObjs)
{
if (obj->ID != Obj::CREATURE_GENERATOR1) //TODO: what with other creature generators?
continue;
auto d = dynamic_cast<const CGDwelling *>(obj);
BOOST_FOREACH (auto creature, d->creatures)
{
if (creature.first) //there are more than 0 creatures avaliabe
{
BOOST_FOREACH (auto type, creature.second)
{
if (type == objid)
dwellings.push_back(d);
}
}
}
}
if (dwellings.size())
{
boost::sort(dwellings, isCloser);
return CGoal(GET_OBJ).setobjid (dwellings.front()->id); //TODO: consider needed resources
}
else
return CGoal(EXPLORE);
//TODO: exchange troops between heroes
}
break;
case CONQUER: //TODO: put it into a function?
{
auto hs = cb->getHeroesInfo();

View File

@ -73,6 +73,7 @@ enum EGoals
RECRUIT_HERO,
BUILD_STRUCTURE, //if hero set, then in visited town
COLLECT_RES,
GATHER_TROOPS, // val of creatures with objid
OBJECT_GOALS_BEGIN,
GET_OBJ, //visit or defeat or collect the object

View File

@ -204,6 +204,7 @@ namespace Obj
MINE = 53,
MONSTER = 54,
OBELISK = 57,
PRISON = 62,
PYRAMID = 63,
SEER_HUT = 83,
CRYPT = 84,

View File

@ -312,6 +312,7 @@ DLL_LINKAGE void RemoveObject::applyGs( CGameState *gs )
auto quest = dynamic_cast<const CQuest *>(obj);
if (quest)
{
gs->map->quests[quest->qid] = NULL;
BOOST_FOREACH (auto &player, gs->players)
{
BOOST_FOREACH (auto &q, player.second.quests)
@ -323,6 +324,7 @@ DLL_LINKAGE void RemoveObject::applyGs( CGameState *gs )
}
}
}
//gs->map->quests[quest->qid].dellNull();
}
gs->map->objects[id].dellNull();

View File

@ -559,7 +559,6 @@ CGHeroInstance * Mapa::getHero(int ID, int mode)
int Mapa::loadSeerHut( const ui8 * bufor, int i, CGObjectInstance *& nobj )
{
CGSeerHut *hut = new CGSeerHut();
addQuest (hut);
nobj = hut;
if(version>RoE)
@ -1464,6 +1463,7 @@ void Mapa::readObjects( const ui8 * bufor, int &i)
case 83: //seer's hut
{
i = loadSeerHut(bufor, i, nobj);
addQuest (dynamic_cast<CQuest *>(nobj));
break;
}
case 113: //witch hut
@ -1724,6 +1724,7 @@ void Mapa::readObjects( const ui8 * bufor, int &i)
CGQuestGuard *guard = new CGQuestGuard();
nobj = guard;
loadQuest(guard, bufor, i);
addQuest (dynamic_cast <CQuest *>(guard));
break;
}
case 28: //faerie ring
@ -1948,7 +1949,6 @@ bool Mapa::isInTheMap(const int3 &pos) const
void Mapa::loadQuest(CQuest * guard, const ui8 * bufor, int & i)
{
addQuest (guard);
guard->missionType = bufor[i]; ++i;
//int len1, len2, len3;
switch(guard->missionType)