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); markObjectVisited (visitedObj);
remove_if_present(reservedObjs, visitedObj); //unreserve objects remove_if_present(reservedObjs, visitedObj); //unreserve objects
remove_if_present(reservedHeroesMap[visitor], visitedObj); 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; MetaString ms;
q.quest->getRolloverText(ms, false); q.quest->getRolloverText(ms, false);
BNLOG ("Trying to realize quest: %s", ms.toString()); BNLOG ("Trying to realize quest: %s", ms.toString());
auto heroes = cb->getHeroesInfo();
switch (q.quest->missionType) switch (q.quest->missionType)
{ {
case CQuest::MISSION_ART: 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) BOOST_FOREACH (auto art, q.quest->m5arts)
{ {
striveToGoal (CGoal(GET_ART_TYPE).setaid(art)); //TODO: transport? striveToGoal (CGoal(GET_ART_TYPE).setaid(art)); //TODO: transport?
@ -2097,33 +2108,49 @@ void VCAI::striveToQuest (const QuestInfo &q)
case CQuest::MISSION_HERO: case CQuest::MISSION_HERO:
{ {
//striveToGoal (CGoal(RECRUIT_HERO)); //striveToGoal (CGoal(RECRUIT_HERO));
auto heroes = cb->getHeroesInfo();
BOOST_FOREACH (auto hero, heroes) BOOST_FOREACH (auto hero, heroes)
{ {
if (q.quest->checkQuest(hero)) if (q.quest->checkQuest(hero))
{ {
striveToGoal (CGoal(GET_OBJ).setobjid(q.obj->id).sethero(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; break;
} }
case CQuest::MISSION_ARMY: 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) 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; break;
} }
case CQuest::MISSION_RESOURCES: 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(VISIT_TILE).settile(q.tile));
striveToGoal (CGoal(COLLECT_RES).setresID(i).setvalue(q.quest->m7resources[i])); }
//TODO: visit object 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; break;
} }
@ -2145,7 +2172,7 @@ void VCAI::striveToQuest (const QuestInfo &q)
if (q.quest->checkQuest(hero)) if (q.quest->checkQuest(hero))
{ {
striveToGoal (CGoal(GET_OBJ).setobjid(q.obj->id).sethero(hero)); striveToGoal (CGoal(GET_OBJ).setobjid(q.obj->id).sethero(hero));
break; return;
} }
} }
for (int i = 0; i < q.quest->m2stats.size(); ++i) 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)) if (q.quest->checkQuest(hero))
{ {
striveToGoal (CGoal(GET_OBJ).setobjid(q.obj->id).sethero(hero)); striveToGoal (CGoal(VISIT_TILE).settile(q.tile).sethero(hero)); //TODO: causes infinite loop :/
break; return;
} }
} }
BNLOG ("Don't know how to reach hero level %d\n", q.quest->m13489val); BNLOG ("Don't know how to reach hero level %d\n", q.quest->m13489val);
@ -2651,6 +2678,7 @@ TSubgoal CGoal::whatToDoToAchieve()
//save? //save?
break; break;
case EVictoryConditionType::GATHERTROOP: case EVictoryConditionType::GATHERTROOP:
return CGoal(GATHER_TROOPS).setobjid(vc.ID).setvalue(vc.count);
break; break;
case EVictoryConditionType::TAKEDWELLINGS: case EVictoryConditionType::TAKEDWELLINGS:
break; break;
@ -2939,6 +2967,53 @@ TSubgoal CGoal::whatToDoToAchieve()
} }
} }
return CGoal(INVALID); 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? case CONQUER: //TODO: put it into a function?
{ {
auto hs = cb->getHeroesInfo(); auto hs = cb->getHeroesInfo();

View File

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

View File

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

View File

@ -312,6 +312,7 @@ DLL_LINKAGE void RemoveObject::applyGs( CGameState *gs )
auto quest = dynamic_cast<const CQuest *>(obj); auto quest = dynamic_cast<const CQuest *>(obj);
if (quest) if (quest)
{ {
gs->map->quests[quest->qid] = NULL;
BOOST_FOREACH (auto &player, gs->players) BOOST_FOREACH (auto &player, gs->players)
{ {
BOOST_FOREACH (auto &q, player.second.quests) 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(); 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 ) int Mapa::loadSeerHut( const ui8 * bufor, int i, CGObjectInstance *& nobj )
{ {
CGSeerHut *hut = new CGSeerHut(); CGSeerHut *hut = new CGSeerHut();
addQuest (hut);
nobj = hut; nobj = hut;
if(version>RoE) if(version>RoE)
@ -1464,6 +1463,7 @@ void Mapa::readObjects( const ui8 * bufor, int &i)
case 83: //seer's hut case 83: //seer's hut
{ {
i = loadSeerHut(bufor, i, nobj); i = loadSeerHut(bufor, i, nobj);
addQuest (dynamic_cast<CQuest *>(nobj));
break; break;
} }
case 113: //witch hut case 113: //witch hut
@ -1724,6 +1724,7 @@ void Mapa::readObjects( const ui8 * bufor, int &i)
CGQuestGuard *guard = new CGQuestGuard(); CGQuestGuard *guard = new CGQuestGuard();
nobj = guard; nobj = guard;
loadQuest(guard, bufor, i); loadQuest(guard, bufor, i);
addQuest (dynamic_cast <CQuest *>(guard));
break; break;
} }
case 28: //faerie ring 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) void Mapa::loadQuest(CQuest * guard, const ui8 * bufor, int & i)
{ {
addQuest (guard);
guard->missionType = bufor[i]; ++i; guard->missionType = bufor[i]; ++i;
//int len1, len2, len3; //int len1, len2, len3;
switch(guard->missionType) switch(guard->missionType)