I recently wrote an AI method like this:
It's not really necessary for my question to understand what a "rebuild move" is, but if you are familiar with unit AI you probably have seen this pattern before: iterate all cities, filter to the ones that are applicable, can be reached and are not already targeted by the same mission, and the select the "best" one.
My question here is about the "reachable" part that uses the AI logic for pathfinding. I originally forgot the "if generatePath" check in the for loop, which resulted in a bug where I assigned a target city to the unit that it could not path to and would instead keep idling in its current location.
The cause of my confusion is what this function considers "pathable". When debugging this issue I found units that would not move even though when I took control of them I could easily order them there manually. The route certainly was through friendly territory with no enemy units around. I tried multiple "AI flags" as well, neither made a difference.
My eventual "fix" was to check for reachability before even considering the city. The outcome was that the mission was not considered and the unit could do something else. However I was not able to get it to actually go there even though it clearly should be possible to.
What's going on? Am I misunderstanding how "generatePath" works? What is the equivalent code to the pathing shown to the human player?
Edit: when writing this I realised that this code misses the part where the unit checks if it already is at the target location and executes the intended rebuild mission. However that does not explain the behaviour I saw - it also occurred if the current plot and the target plot were different.
Code:
bool CvUnitAI::AI_rebuildMove(int iMinimumCost)
{
CvCity* pBestCity = NULL;
int iBestProduction = 0;
int iLoop, iCurrentProduction;
for (CvCity* pLoopCity = GET_PLAYER(getOwnerINLINE()).firstCity(&iLoop); pLoopCity != NULL; pLoopCity = GET_PLAYER(getOwnerINLINE()).nextCity(&iLoop))
{
if (GET_PLAYER(getOwnerINLINE()).AI_plotTargetMissionAIs(pLoopCity->plot(), MISSIONAI_REBUILD) == 0)
{
if (generatePath(pLoopCity->plot(), MOVE_SAFE_TERRITORY, true))
{
iCurrentProduction = pLoopCity->getRebuildProduction();
if (iCurrentProduction >= iMinimumCost && iCurrentProduction > iBestProduction)
{
pBestCity = pLoopCity;
iBestProduction = iCurrentProduction;
}
}
}
}
if (pBestCity != NULL)
{
getGroup()->pushMission(MISSION_MOVE_TO, pBestCity->getX(), pBestCity->getY(), MOVE_SAFE_TERRITORY, false, false, MISSIONAI_REBUILD);
return true;
}
return false;
}
My question here is about the "reachable" part that uses the AI logic for pathfinding. I originally forgot the "if generatePath" check in the for loop, which resulted in a bug where I assigned a target city to the unit that it could not path to and would instead keep idling in its current location.
The cause of my confusion is what this function considers "pathable". When debugging this issue I found units that would not move even though when I took control of them I could easily order them there manually. The route certainly was through friendly territory with no enemy units around. I tried multiple "AI flags" as well, neither made a difference.
My eventual "fix" was to check for reachability before even considering the city. The outcome was that the mission was not considered and the unit could do something else. However I was not able to get it to actually go there even though it clearly should be possible to.
What's going on? Am I misunderstanding how "generatePath" works? What is the equivalent code to the pathing shown to the human player?
Edit: when writing this I realised that this code misses the part where the unit checks if it already is at the target location and executes the intended rebuild mission. However that does not explain the behaviour I saw - it also occurred if the current plot and the target plot were different.