mirror of
https://github.com/vcmi/vcmi.git
synced 2025-03-25 21:38:59 +02:00
- Fixes for Quest Guard and goal completion, in particular For Sale map (#894)
- Fixes for ally players handling by AI
This commit is contained in:
parent
0c3ccda922
commit
a8539b2b28
@ -258,7 +258,17 @@ TSubgoal GetObj::whatToDoToAchieve()
|
||||
if(!obj)
|
||||
return sptr (Goals::Explore());
|
||||
int3 pos = obj->visitablePos();
|
||||
return sptr (Goals::VisitTile(pos).sethero(hero)); //we must visit object with same hero, if any
|
||||
if (hero)
|
||||
{
|
||||
if (ai->isAccessibleForHero(pos, hero))
|
||||
return sptr (Goals::VisitTile(pos).sethero(hero));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (isReachable(obj))
|
||||
return sptr (Goals::VisitTile(pos).sethero(hero)); //we must visit object with same hero, if any
|
||||
}
|
||||
return sptr (Goals::ClearWayTo(pos).sethero(hero));
|
||||
}
|
||||
|
||||
float GetObj::importanceWhenLocked() const
|
||||
@ -266,10 +276,9 @@ float GetObj::importanceWhenLocked() const
|
||||
return 3;
|
||||
}
|
||||
|
||||
|
||||
bool GetObj::fulfillsMe (shared_ptr<VisitTile> goal)
|
||||
bool GetObj::fulfillsMe (TSubgoal goal)
|
||||
{
|
||||
if (cb->getObj(ObjectInstanceID(objid))->visitablePos() == goal->tile)
|
||||
if (goal->goalType == Goals::VISIT_TILE && cb->getObj(ObjectInstanceID(objid))->visitablePos() == goal->tile)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
@ -305,9 +314,9 @@ float VisitHero::importanceWhenLocked() const
|
||||
return 4;
|
||||
}
|
||||
|
||||
bool VisitHero::fulfillsMe (shared_ptr<VisitTile> goal)
|
||||
bool VisitHero::fulfillsMe (TSubgoal goal)
|
||||
{
|
||||
if (cb->getObj(ObjectInstanceID(objid))->visitablePos() == goal->tile)
|
||||
if (goal->goalType == Goals::VISIT_TILE && cb->getObj(ObjectInstanceID(objid))->visitablePos() == goal->tile)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
@ -355,18 +364,24 @@ TGoalVec ClearWayTo::getAllPossibleSubgoals()
|
||||
ret.push_back (sptr (Goals::FindObj (Obj::KEYMASTER, cb->getTile(tileToHit)->visitableObjects.back()->subID)));
|
||||
}
|
||||
|
||||
////FIXME: this code shouldn't be necessary
|
||||
//if(tileToHit == tile)
|
||||
//{
|
||||
// logAi->errorStream() << boost::format("Very strange, tile to hit is %s and tile is also %s, while hero %s is at %s\n")
|
||||
// % tileToHit % tile % h->name % h->visitablePos();
|
||||
// throw cannotFulfillGoalException("Retrieving first tile to hit failed (probably)!");
|
||||
//}
|
||||
|
||||
auto topObj = backOrNull(cb->getVisitableObjs(tileToHit));
|
||||
if(topObj && topObj->ID == Obj::HERO && cb->getPlayerRelations(h->tempOwner, topObj->tempOwner) != PlayerRelations::ENEMIES)
|
||||
if(topObj)
|
||||
{
|
||||
logAi->errorStream() << boost::format("%s stands in the way of %s.\n") % topObj->getHoverText() % h->getHoverText();
|
||||
if (topObj->ID == Obj::HERO && cb->getPlayerRelations(h->tempOwner, topObj->tempOwner) != PlayerRelations::ENEMIES)
|
||||
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)
|
||||
{
|
||||
if (shouldVisit(h, topObj))
|
||||
{
|
||||
//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)));
|
||||
}
|
||||
else
|
||||
{
|
||||
//TODO: we should be able to return apriopriate quest here (VCAI::striveToQuest)
|
||||
logAi->debugStream() << "Quest guard blocks the way to " + tile();
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
ret.push_back (sptr (Goals::VisitTile(tileToHit).sethero(h)));
|
||||
@ -375,7 +390,10 @@ TGoalVec ClearWayTo::getAllPossibleSubgoals()
|
||||
ret.push_back (sptr (Goals::RecruitHero()));
|
||||
|
||||
if (ret.empty())
|
||||
throw cannotFulfillGoalException("There is no known way to clear the way to tile " + tile());
|
||||
{
|
||||
logAi->warnStream() << "There is no known way to clear the way to tile " + tile();
|
||||
throw goalFulfilledException (sptr(*this)); //make sure asigned hero gets unlocked
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -642,7 +660,7 @@ TSubgoal CollectRes::whatToDoToAchieve()
|
||||
}
|
||||
}
|
||||
}
|
||||
return sptr (Goals::Invalid()); //FIXME: unused?
|
||||
return sptr (setisElementar(true)); //all the conditions for trade are met
|
||||
}
|
||||
|
||||
float CollectRes::importanceWhenLocked() const
|
||||
@ -916,5 +934,3 @@ float CGoal<T>::accept (FuzzyHelper * f)
|
||||
{
|
||||
return f->evaluate(static_cast<T&>(*this)); //casting enforces template instantiation
|
||||
}
|
||||
|
||||
|
||||
|
@ -116,15 +116,10 @@ public:
|
||||
{
|
||||
return false;
|
||||
}
|
||||
virtual bool fulfillsMe (Goals::TSubgoal goal)
|
||||
virtual bool fulfillsMe (Goals::TSubgoal goal) //TODO: multimethod instead of type check
|
||||
{
|
||||
return false;
|
||||
}
|
||||
virtual bool fulfillsMe (shared_ptr<VisitTile> goal)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
//template <typename Handler> void serialize(Handler &h, const int version)
|
||||
//{
|
||||
@ -301,7 +296,7 @@ public:
|
||||
TGoalVec getAllPossibleSubgoals() override {return TGoalVec();};
|
||||
TSubgoal whatToDoToAchieve() override;
|
||||
bool operator== (GetObj &g) {return g.objid == objid;}
|
||||
bool fulfillsMe (shared_ptr<VisitTile> goal) override;
|
||||
bool fulfillsMe (TSubgoal goal) override;
|
||||
std::string completeMessage() const override;
|
||||
float importanceWhenLocked() const override;
|
||||
};
|
||||
@ -325,7 +320,7 @@ public:
|
||||
TGoalVec getAllPossibleSubgoals() override {return TGoalVec();};
|
||||
TSubgoal whatToDoToAchieve() override;
|
||||
bool operator== (VisitHero &g) {return g.objid == objid;}
|
||||
bool fulfillsMe (shared_ptr<VisitTile> goal) override;
|
||||
bool fulfillsMe (TSubgoal goal) override;
|
||||
std::string completeMessage() const override;
|
||||
float importanceWhenLocked() const override;
|
||||
};
|
||||
|
@ -1153,7 +1153,7 @@ bool VCAI::isGoodForVisit(const CGObjectInstance *obj, HeroPtr h)
|
||||
const int3 pos = obj->visitablePos();
|
||||
if (isAccessibleForHero(obj->visitablePos(), h) &&
|
||||
!obj->wasVisited(playerID) &&
|
||||
(obj->tempOwner != playerID || isWeeklyRevisitable(obj)) && //flag or get weekly resources / creatures
|
||||
(cb->getPlayerRelations(ai->playerID, obj->tempOwner) == PlayerRelations::ENEMIES || isWeeklyRevisitable(obj)) && //flag or get weekly resources / creatures
|
||||
isSafeToVisit(h, pos) &&
|
||||
shouldVisit(h, obj) &&
|
||||
!vstd::contains(alreadyVisited, obj) &&
|
||||
@ -1505,7 +1505,9 @@ bool VCAI::isAccessibleForHero(const int3 & pos, HeroPtr h, bool includeAllies /
|
||||
{ //don't visit tile occupied by allied hero
|
||||
for (auto obj : cb->getVisitableObjs(pos))
|
||||
{
|
||||
if (obj->ID == Obj::HERO && obj->tempOwner == h->tempOwner && obj != h.get())
|
||||
if (obj->ID == Obj::HERO &&
|
||||
cb->getPlayerRelations(ai->playerID, obj->tempOwner) != PlayerRelations::ENEMIES &&
|
||||
obj != h.get())
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -1614,7 +1616,6 @@ void VCAI::tryRealize(Goals::RecruitHero & g)
|
||||
|
||||
void VCAI::tryRealize(Goals::VisitTile & g)
|
||||
{
|
||||
//cb->recalculatePaths();
|
||||
if(!g.hero->movement)
|
||||
throw cannotFulfillGoalException("Cannot visit tile: hero is out of MPs!");
|
||||
if(g.tile == g.hero->visitablePos() && cb->getVisitableObjs(g.hero->visitablePos()).size() < 2)
|
||||
@ -1623,15 +1624,10 @@ void VCAI::tryRealize(Goals::VisitTile & g)
|
||||
% g.hero->name % g.tile;
|
||||
throw goalFulfilledException (sptr(g));
|
||||
}
|
||||
//if(!g.isBlockedBorderGate(g.tile))
|
||||
//{
|
||||
if (ai->moveHeroToTile(g.tile, g.hero.get()))
|
||||
{
|
||||
throw goalFulfilledException (sptr(g));
|
||||
}
|
||||
//}
|
||||
//else
|
||||
// throw cannotFulfillGoalException("There's a blocked gate!, we should never be here"); //CLEAR_WAY_TO should get keymaster tent
|
||||
if (ai->moveHeroToTile(g.tile, g.hero.get()))
|
||||
{
|
||||
throw goalFulfilledException (sptr(g));
|
||||
}
|
||||
}
|
||||
|
||||
void VCAI::tryRealize(Goals::VisitHero & g)
|
||||
@ -1953,7 +1949,7 @@ void VCAI::striveToQuest (const QuestInfo &q)
|
||||
{
|
||||
if (q.quest->checkQuest(heroes.front())) //it doesn't matter which hero it is
|
||||
{
|
||||
striveToGoal (sptr(Goals::VisitTile(q.tile)));
|
||||
striveToGoal (sptr(Goals::GetObj(q.obj->id.getNum())));
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1975,7 +1971,7 @@ void VCAI::striveToQuest (const QuestInfo &q)
|
||||
if (obj)
|
||||
striveToGoal (sptr(Goals::GetObj(obj->id.getNum())));
|
||||
else
|
||||
striveToGoal (sptr(Goals::VisitTile(q.tile))); //visit seer hut
|
||||
striveToGoal (sptr(Goals::GetObj(q.obj->id.getNum()))); //visit seer hut
|
||||
break;
|
||||
}
|
||||
case CQuest::MISSION_PRIMARY_STAT:
|
||||
@ -2002,7 +1998,7 @@ void VCAI::striveToQuest (const QuestInfo &q)
|
||||
{
|
||||
if (q.quest->checkQuest(hero))
|
||||
{
|
||||
striveToGoal (sptr(Goals::VisitTile(q.tile).sethero(hero))); //TODO: causes infinite loop :/
|
||||
striveToGoal (sptr(Goals::GetObj(q.obj->id.getNum()).sethero(hero))); //TODO: causes infinite loop :/
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user