I'm trying to build my own mod, based on KMOD. It adds AI-compatible multiplayer-friendly revolution mechanics.
There is an FAssert during debug. It doesn't crash the game, but cargo units are called stranded in AI_cityDefenseMove.
There is an FAssert during debug. It doesn't crash the game, but cargo units are called stranded in AI_cityDefenseMove.
Code:
// K-Mod
// Decide whether or not this group is stranded.
// If they are stranded, try to walk towards the coast.
// If we're on the coast, wait to be rescued!
bool CvUnitAI::AI_handleStranded(int iFlags)
{
PROFILE_FUNC();
if (isCargo())
{
// This is possible, in some rare cases, but I'm currently trying to pin down precisely what those cases are.
FAssertMsg(false, "AI_handleStranded: this unit is already cargo.");
getGroup()->pushMission(MISSION_SKIP);
return true;
}
if (isHuman())
return false;
const CvPlayerAI& kOwner = GET_PLAYER(getOwnerINLINE());
// return false if the group is not stranded.
int iDummy;
if (area()->getNumAIUnits(getOwnerINLINE(), UNITAI_SETTLE) > 0 && kOwner.AI_getNumAreaCitySites(getArea(), iDummy) > 0)
{
return false;
}
if (area()->getNumCities() > 0)
{
if (plot()->getTeam() == getTeam())
return false;
if (getGroup()->isHasPathToAreaPlayerCity(getOwnerINLINE(), iFlags))
{
return false;
}
if ((canFight() || isSpy()) && getGroup()->isHasPathToAreaEnemyCity(true, iFlags))
{
return false;
}
}
// ok.. so the group is standed.
// Try to get to the coast.
if (!plot()->isCoastalLand())
{
// maybe we were already on our way?
CvPlot* pMissionPlot = 0;
CvPlot* pEndTurnPlot = 0;
if (getGroup()->AI_getMissionAIType() == MISSIONAI_STRANDED)
{
pMissionPlot = getGroup()->AI_getMissionAIPlot();
if (pMissionPlot && pMissionPlot->isCoastalLand() && !pMissionPlot->isVisibleEnemyUnit(this) && generatePath(pMissionPlot, iFlags, true))
{
// The current mission looks good enough. Don't bother searching for a better option.
pEndTurnPlot = getPathEndTurnPlot();
}
else
{
// the current mission plot is not suitable. We'll have to search.
pMissionPlot = 0;
}
}
if (!pMissionPlot)
{
// look for the clostest coastal plot in this area
int iShortestPath = MAX_INT;
for (int i = 0; i < GC.getMapINLINE().numPlotsINLINE(); i++)
{
CvPlot* pLoopPlot = GC.getMapINLINE().plotByIndexINLINE(i);
if (pLoopPlot->getArea() == getArea() && pLoopPlot->isCoastalLand())
{
// TODO: check that the water isnt' blocked by ice.
int iPathTurns;
if (generatePath(pLoopPlot, iFlags, true, &iPathTurns, iShortestPath))
{
FAssert(iPathTurns <= iShortestPath);
iShortestPath = iPathTurns;
pEndTurnPlot = getPathEndTurnPlot();
pMissionPlot = pLoopPlot;
if (iPathTurns <= 1)
break;
}
}
}
}
if (pMissionPlot)
{
FAssert(pEndTurnPlot);
getGroup()->pushMission(MISSION_MOVE_TO, pEndTurnPlot->getX_INLINE(), pEndTurnPlot->getY_INLINE(), iFlags, false, false, MISSIONAI_STRANDED, pMissionPlot);
return true;
}
}
// Hopefully we're on the coast. (but we might not be - if we couldn't find a path to the coast)
// try to load into a passing boat
// Calling AI_load will check all of our boats; so before we do that, I'm going to just see if there are any boats on adjacent plots.
for (int i = NO_DIRECTION; i < NUM_DIRECTION_TYPES; i++)
{
CvPlot* pAdjacentPlot = plotDirection(getX_INLINE(), getY_INLINE(), (DirectionTypes)i);
if (pAdjacentPlot && canLoad(pAdjacentPlot))
{
// ok. there is something we can load into - but lets use the (slow) official function to actually issue the load command.
if (AI_load(NO_UNITAI, NO_MISSIONAI, NO_UNITAI, -1, -1, -1, -1, iFlags, 1))
return true;
else // if that didn't do it, nothing will
break;
}
}
// raise the 'stranded' flag, and wait to be rescued.
getGroup()->pushMission(MISSION_SKIP, -1, -1, 0, false, false, MISSIONAI_STRANDED, plot());
return true;
}
// K-Mod end