cf_nz
Prince
Recently I've been experiencing crashes with Civ4 and have made an assert build to try and figure out the cause, unfortunately my C++ skills are limited so I'm only vaguely aware of what I'm doing. I've posted in Dales thread to see what is likely to trigger this assert but I'll post here as well. Thanks to anyone for their assistance. (My game consists of a merge of BetterAI; Dales Ranged Bombardment; Influence driven War and Route Pillage).
----------------------
Assert Failed
File: CvUnitAI.cpp
Line: 13827
Expression: pDefender != NULL
Message:
----------------------
The offending section of code; I've bolded line 13827.
----------------------
Assert Failed
File: CvUnitAI.cpp
Line: 13827
Expression: pDefender != NULL
Message:
----------------------
The offending section of code; I've bolded line 13827.
Code:
// Dale - Field Bombard: modified to allow AI to use new ranged bombardment method
// Returns true if a mission was pushed...
bool CvUnitAI::AI_bombardCity()
{
PROFILE_FUNC();
CvCity* pCity;
CvCity* pBombardCity;
CvPlot* pLoopPlot;
CvPlot* pBestPlot;
CvUnit* pDefender;
int iSearchRange;
int iPotentialAttackers;
int iValue;
int iDamage;
int iBestValue;
int iDX, iDY;
if(!canBombard(plot()))
{
return false;
}
if(DCMFieldBombard)
{
iSearchRange = getDCMBombRange();
iBestValue = 0;
pBestPlot = NULL;
for (iDX = -(iSearchRange); iDX <= iSearchRange; iDX++)
{
for (iDY = -(iSearchRange); iDY <= iSearchRange; iDY++)
{
pLoopPlot = plotXY(getX_INLINE(), getY_INLINE(), iDX, iDY);
if (pLoopPlot != NULL)
{
if (canBombardAtRanged(plot(), pLoopPlot->getX_INLINE(), pLoopPlot->getY_INLINE()))
{
iValue = 0;
pCity = pLoopPlot->getPlotCity();
if (pCity != NULL)
{
iValue += max(0, (min((pCity->getDefenseDamage() + airBombCurrRate()), GC.getMAX_CITY_DEFENSE_DAMAGE()) - pCity->getDefenseDamage()));
iValue *= 5;
if (pCity->AI_isDanger())
{
iValue *= 2;
}
if (pCity == pCity->area()->getTargetCity(getOwnerINLINE()))
{
iValue *= 3;
}
}
iPotentialAttackers = GET_PLAYER(getOwnerINLINE()).AI_adjacentPotentialAttackers(pLoopPlot);//pLoopPlot->getNumVisibleEnemyDefenders(NO_PLAYER);
if (iPotentialAttackers > 0 || pLoopPlot->isAdjacentTeam(getTeam()))
{
pDefender = pLoopPlot->getBestDefender(NO_PLAYER, getOwnerINLINE(), this, true);
[B]FAssert(pDefender != NULL);[/B]
FAssert(pDefender->canDefend());
iDamage = GC.getGameINLINE().getSorenRandNum(bombardRate(), "AI Bombard");
// iValue = max(0, (min((pDefender->getDamage() + iDamage), bombardRate()) - pDefender->getDamage()));
iValue += ((((iDamage * collateralDamage()) / 100) * min((pLoopPlot->getNumVisibleEnemyDefenders(getOwnerINLINE()) - 1), collateralDamageMaxUnits())) / 2);
iValue *= (3 + iPotentialAttackers);
iValue /= 4;
}
iValue *= GC.getGameINLINE().getSorenRandNum(20, "AI Bombard");
if (iValue > iBestValue)
{
iBestValue = iValue;
pBestPlot = pLoopPlot;
FAssert(!atPlot(pBestPlot));
}
}
}
}
}
if (pBestPlot != NULL)
{
getGroup()->pushMission(MISSION_BOMBARD, pBestPlot->getX_INLINE(), pBestPlot->getY_INLINE());
return true;
}
return false;
} else {
if (canBombard(plot()))
{
pBombardCity = bombardTarget(plot());
FAssertMsg(pBombardCity != NULL, "BombardCity is not assigned a valid value");
-------BetterAI addition start-------
// do not bombard cities with no defenders
int iDefenderStrength = pBombardCity->plot()->AI_sumStrength(NO_PLAYER, getOwnerINLINE(), DOMAIN_LAND, true, true, false);
if (iDefenderStrength == 0)
{
return false;
}
// do not bombard cities if we have overwelming odds
int iAttackOdds = getGroup()->AI_attackOdds(pBombardCity->plot(), true);
if (iAttackOdds > 95)
{
return false;
}
// could also do a compare stacks call here if we wanted, the downside of that is that we may just have a lot more units
// we may not want to suffer high casualties just to save a turn
//getGroup()->AI_compareStacks(pBombardCity->plot(), true, true, true);
//int iOurStrength = pBombardCity->plot()->AI_sumStrength(getOwnerINLINE(), NO_PLAYER, DOMAIN_LAND, false, false, false)
----------BetterAI addition end----------
if (pBombardCity->getDefenseDamage() < ((GC.getMAX_CITY_DEFENSE_DAMAGE() * 3) / 4))
{
getGroup()->pushMission(MISSION_BOMBARD);
return true;
}
}
return false;
}
}