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:
parent
9207e4f4a4
commit
356e675a65
@ -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();
|
||||||
|
@ -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
|
||||||
|
@ -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,
|
||||||
|
@ -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();
|
||||||
|
@ -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)
|
||||||
|
Loading…
Reference in New Issue
Block a user