1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-11-26 08:41:13 +02:00

- Fixed some more cases when heroes could block each other

- More generous checking of complete goals and their dependencies
This commit is contained in:
DjWarmonger 2013-11-24 19:15:08 +00:00
parent b0bdfff117
commit 54c52869cf
4 changed files with 45 additions and 21 deletions

View File

@ -191,7 +191,7 @@ TSubgoal FindObj::whatToDoToAchieve()
}
}
}
if (o && isReachable(o))
if (o && isReachable(o)) //we don't use isAccessibleForHero as we don't know which hero it is
return sptr (Goals::GetObj(o->id.getNum()));
else
return sptr (Goals::Explore());
@ -210,6 +210,14 @@ TSubgoal GetObj::whatToDoToAchieve()
return sptr (Goals::VisitTile(pos));
}
bool GetObj::fulfillsMe (shared_ptr<VisitTile> goal)
{
if (cb->getObj(ObjectInstanceID(objid))->visitablePos() == goal->tile)
return true;
else
return false;
}
std::string VisitHero::completeMessage() const
{
return "hero " + hero.get()->name + " visited hero " + boost::lexical_cast<std::string>(objid);
@ -231,6 +239,14 @@ TSubgoal VisitHero::whatToDoToAchieve()
return sptr (Goals::Invalid());
}
bool VisitHero::fulfillsMe (shared_ptr<VisitTile> goal)
{
if (cb->getObj(ObjectInstanceID(objid))->visitablePos() == goal->tile)
return true;
else
return false;
}
TSubgoal GetArtOfType::whatToDoToAchieve()
{
TSubgoal alternativeWay = CGoal::lookForArtSmart(aid); //TODO: use
@ -718,7 +734,7 @@ TSubgoal GatherArmy::whatToDoToAchieve()
{
if(!t->visitingHero && howManyReinforcementsCanGet(hero,t))
{
if(isReachable(t) && !vstd::contains (ai->townVisitsThisWeek[hero], t))
if (ai->isAccessibleForHero(t->pos, hero) && !vstd::contains (ai->townVisitsThisWeek[hero], t))
townsReachable.push_back(t);
}
}

View File

@ -22,6 +22,7 @@ class VCAI;
namespace Goals
{
struct AbstractGoal;
class VisitTile;
typedef std::shared_ptr<Goals::AbstractGoal> TSubgoal;
typedef std::vector<TSubgoal> TGoalVec;
@ -108,6 +109,14 @@ public:
{
return false;
}
virtual bool fulfillsMe (Goals::TSubgoal goal)
{
return false;
}
virtual bool fulfillsMe (shared_ptr<VisitTile> goal)
{
return false;
}
//template <typename Handler> void serialize(Handler &h, const int version)
@ -259,6 +268,7 @@ public:
GetObj(int Objid) : CGoal(Goals::GET_OBJ) {objid = Objid;};
TSubgoal whatToDoToAchieve() override;
bool operator== (GetObj &g) {return g.objid == objid;}
bool fulfillsMe (shared_ptr<VisitTile> goal) override;
std::string completeMessage() const override;
};
class FindObj : public CGoal<FindObj>
@ -278,6 +288,7 @@ public:
VisitHero(int hid) : CGoal (Goals::VISIT_HERO){objid = hid;};
TSubgoal whatToDoToAchieve() override;
bool operator== (VisitHero &g) {return g.objid == objid;}
bool fulfillsMe (shared_ptr<VisitTile> goal) override;
std::string completeMessage() const override;
};
class GetArtOfType : public CGoal<GetArtOfType>

View File

@ -259,7 +259,8 @@ void VCAI::heroVisit(const CGHeroInstance *visitor, const CGObjectInstance *visi
markObjectVisited (visitedObj);
erase_if_present(reservedObjs, visitedObj); //unreserve objects
erase_if_present(reservedHeroesMap[visitor], visitedObj);
completeGoal (sptr(Goals::GetObj(visitedObj->id.getNum()).sethero(visitor))); //we don't need to visit in anymore
completeGoal (sptr(Goals::GetObj(visitedObj->id.getNum()).sethero(visitor))); //we don't need to visit it anymore
//TODO: what if we visited one-time visitable object that was reserved by another hero (shouldn't, but..)
}
status.heroVisit(visitedObj, start);
@ -1083,7 +1084,7 @@ std::vector<const CGObjectInstance *> VCAI::getPossibleDestinations(HeroPtr h)
std::vector<const CGObjectInstance *> possibleDestinations;
for(const CGObjectInstance *obj : visitableObjs)
{
if(cb->getPathInfo(obj->visitablePos())->reachable() && !obj->wasVisited(playerID) &&
if(isAccessibleForHero(obj->visitablePos(), h) && !obj->wasVisited(playerID) &&
(obj->tempOwner != playerID || isWeeklyRevisitable(obj))) //flag or get weekly resources / creatures
possibleDestinations.push_back(obj);
}
@ -1122,8 +1123,15 @@ void VCAI::wander(HeroPtr h)
while(1)
{
validateVisitableObjs();
std::vector <ObjectIdRef> dests;
range::copy(reservedHeroesMap[h], std::back_inserter(dests));
std::vector <ObjectIdRef> dests, tmp;
range::copy(reservedHeroesMap[h], std::back_inserter(tmp)); //visit our reserved objects first
for (auto obj : tmp)
{
if (isAccessibleForHero (obj->visitablePos(), h)) //even nearby objects could be blocked by other heroes :(
dests.push_back(obj); //can't use lambda for member function :(
}
if (!dests.size())
range::copy(getPossibleDestinations(h), std::back_inserter(dests));
@ -1140,7 +1148,7 @@ void VCAI::wander(HeroPtr h)
{
if(!t->visitingHero && howManyReinforcementsCanGet(h,t) && !vstd::contains(townVisitsThisWeek[h], t))
{
if(isReachable(t))
if (isAccessibleForHero (t->visitablePos(), h))
townsReachable.push_back(t);
else
townsNotReachable.push_back(t);
@ -1243,9 +1251,9 @@ void VCAI::completeGoal (Goals::TSubgoal goal)
{
for (auto p : lockedHeroes)
{
if (p.second == goal)
if (p.second == goal || p.second->fulfillsMe(goal)) //we could have fulfilled goals of other heroes by chance
{
logAi->debugStream() << boost::format("%s") % goal->completeMessage();
logAi->debugStream() << boost::format("%s") % p.second->completeMessage();
lockedHeroes.erase (lockedHeroes.find(p.first)); //is it safe?
}
}
@ -1688,16 +1696,6 @@ void VCAI::endTurn()
logAi->debugStream() << "Player " << static_cast<int>(playerID.getNum()) << " ended turn";
}
bool VCAI::fulfillsGoal (Goals::TSubgoal goal, Goals::TSubgoal mainGoal)
{
if (mainGoal->goalType == Goals::GET_OBJ && goal->goalType == Goals::VISIT_TILE) //deduce that GET_OBJ was completed by visiting object's tile
{ //TODO: more universal mechanism
if (cb->getObj(ObjectInstanceID(mainGoal->objid))->visitablePos() == goal->tile)
return true;
}
return false;
}
void VCAI::striveToGoal(Goals::TSubgoal ultimateGoal)
{
if (ultimateGoal->invalid())
@ -1783,7 +1781,7 @@ Goals::TSubgoal VCAI::striveToGoalInternal(Goals::TSubgoal ultimateGoal, bool on
catch(goalFulfilledException &e)
{
completeGoal (goal);
if (fulfillsGoal (goal, ultimateGoal) || maxGoals > 98) //completed goal was main goal //TODO: find better condition
if (ultimateGoal->fulfillsMe(goal) || maxGoals > 98) //completed goal was main goal //TODO: find better condition
return sptr(Goals::Invalid());
}
catch(std::exception &e)

View File

@ -239,7 +239,6 @@ public:
void setGoal(HeroPtr h, Goals::TSubgoal goal);
void completeGoal (Goals::TSubgoal goal); //safely removes goal from reserved hero
void striveToQuest (const QuestInfo &q);
bool fulfillsGoal (Goals::TSubgoal goal, Goals::TSubgoal mainGoal);
void recruitHero(const CGTownInstance * t, bool throwing = false);
std::vector<const CGObjectInstance *> getPossibleDestinations(HeroPtr h);