示例#1
0
文件: Goals.cpp 项目: szpak/vcmi
TGoalVec GatherArmy::getAllPossibleSubgoals()
{
	//get all possible towns, heroes and dwellings we may use
	TGoalVec ret;
	
	//TODO: include evaluation of monsters gather in calculation
	for (auto t : cb->getTownsInfo())
	{
		auto pos = t->visitablePos();
		if (ai->isAccessibleForHero(pos, hero))
		{
			if(!t->visitingHero && howManyReinforcementsCanGet(hero,t))
			{
				if (!vstd::contains (ai->townVisitsThisWeek[hero], t))
					ret.push_back (sptr (Goals::VisitTile(pos).sethero(hero)));
			}
			auto bid = ai->canBuildAnyStructure(t, std::vector<BuildingID>
							(unitsSource, unitsSource + ARRAY_COUNT(unitsSource)), 8 - cb->getDate(Date::DAY_OF_WEEK));
			if (bid != BuildingID::NONE)
				ret.push_back (sptr(BuildThis(bid, t)));
		}
	}

	auto otherHeroes = cb->getHeroesInfo();
	auto heroDummy = hero;
	erase_if(otherHeroes, [heroDummy](const CGHeroInstance * h)
	{
		return (h == heroDummy.h || !ai->isAccessibleForHero(heroDummy->visitablePos(), h, true)
			|| !ai->canGetArmy(heroDummy.h, h) || ai->getGoal(h)->goalType == Goals::GATHER_ARMY);
	});
	for (auto h : otherHeroes)
	{
		ret.push_back (sptr (Goals::VisitHero(h->id.getNum()).setisAbstract(true).sethero(hero)));
				//go to the other hero if we are faster
		ret.push_back (sptr (Goals::VisitHero(hero->id.getNum()).setisAbstract(true).sethero(h)));
				//let the other hero come to us
	}

	std::vector <const CGObjectInstance *> objs;
	for (auto obj : ai->visitableObjs)
	{
		if(obj->ID == Obj::CREATURE_GENERATOR1)
		{
			auto relationToOwner = cb->getPlayerRelations(obj->getOwner(), ai->playerID);

			//Use flagged dwellings only when there are available creatures that we can afford
			if(relationToOwner == PlayerRelations::SAME_PLAYER)
			{
				auto dwelling = dynamic_cast<const CGDwelling*>(obj);
				for(auto & creLevel : dwelling->creatures)
				{
					if(creLevel.first)
					{
						for(auto & creatureID : creLevel.second)
						{
							auto creature = VLC->creh->creatures[creatureID];
							if (ai->freeResources().canAfford(creature->cost))
								objs.push_back(obj);
						}
					}
				}
			}
		}
	}
	for(auto h : cb->getHeroesInfo())
	{
		for (auto obj : objs)
		{ //find safe dwelling
			auto pos = obj->visitablePos();
			if (ai->isGoodForVisit(obj, h))
				ret.push_back (sptr (Goals::VisitTile(pos).sethero(h)));
		}
	}
	if (ai->canRecruitAnyHero()) //this is not stupid in early phase of game
		ret.push_back (sptr(Goals::RecruitHero()));

	if (ret.empty())
	{
		if (hero == ai->primaryHero() || value >= 1.1f)
			ret.push_back (sptr(Goals::Explore()));
		else //workaround to break loop - seemingly there are no ways to explore left
			throw goalFulfilledException (sptr(Goals::GatherArmy(0).sethero(hero)));
	}

	return ret;
}