Maniac
Apolyton Sage
Been a while since I posted a thread here... It's also been a long time since I've had a bug in Planetfall, but alas... good things don't last forever.
I'm having a crash after clicking end turn I can't find the cause of. Perhaps someone with more C++ experience might see the light.
The situation:
1) When I compile an assert DLL, the crash doesn't happen anymore.
2) When I remove random cities or civilizations, the crash doesn't happen anymore. I can't find a particular city or faction causing the problem though. If I remove faction A, B & C, the crash stops. If I remove factions D, E & F - and leave A/B/C intact - the crash doesn't happen either. No pattern I can discover.
3) Then I starting removing some stuff from the DLL which I had added in the latest patch. I found this to be the culprit:
In the latest patch I had removed '+ getNumCities() * 2' from this piece of code. It originally looked like this:
iTempValue += (AI_averageYieldMultiplier((YieldTypes)iI) * (kCivic.getFeatureYieldChanges(iJ, iI) * (countMinCityPopOrFeatures((FeatureTypes)iJ) + getNumCities() * 2))) / 100;
With that change, there is no crash.
Just like removing random cities, changing that line of cide still doesn't give me the cause of the crash though. It might be something seemingly unrelated. So I continued experimenting.
4) Perhaps the problem was with the countMinCityPopOrFeatures function. That's something I created myself, and rewrote too in the latest patch. If I change (countMinCityPopOrFeatures((FeatureTypes)iJ) + getNumCities() * 2) to (getNumCities() * 2), the crash goes away too. Given point 5), I don't think this function is the culprit though. For the record, I will attach the new and old version of this function in spoilers:
5) My next step was to remove the feature loop (that is: for (iJ = 0; iJ < GC.getNumFeatureInfos(); iJ++), etcetera) altogether. Then the crash DOES still occur.
I can't see any pattern:
Remove the feature loop (neither countMinCityPopOrFeatures or getNumCities): crash
Only keep countMinCityPopOrFeatures: crash
Only keep getNumCities: no crash
Have both countMinCityPopOrFeatures or getNumCities: no crash
I mean, WTF!?!
6) I figured perhaps the problem was not caused by those specific values, but perhaps by some AI switching civics. Messing around with the value of a civic might entice/prevent the AI decisions on switching civics. So I changed the code to make an AI's current civic ten times as attractive. It didn't make a difference. Then there is still a crash.
7) Sometimes a crash requires a certain random number being rolled, and making any change (like removing a city) will change the random number rolled, and thus prevent the crash. However there is no random element involved in the AI deciding what civic to pick, so I don't really see how the civic value calculations can influence random crashes.
I guess few will have read this far. -( Does anyone see some pattern in this mess?
I'm having a crash after clicking end turn I can't find the cause of. Perhaps someone with more C++ experience might see the light.
The situation:
1) When I compile an assert DLL, the crash doesn't happen anymore.
2) When I remove random cities or civilizations, the crash doesn't happen anymore. I can't find a particular city or faction causing the problem though. If I remove faction A, B & C, the crash stops. If I remove factions D, E & F - and leave A/B/C intact - the crash doesn't happen either. No pattern I can discover.
3) Then I starting removing some stuff from the DLL which I had added in the latest patch. I found this to be the culprit:
Code:
int CvPlayerAI::AI_civicValue(CivicTypes eCivic)
{
...
for (iI = 0; iI < NUM_YIELD_TYPES; iI++)
{
iTempValue = 0;
...
for (iJ = 0; iJ < GC.getNumFeatureInfos(); iJ++)
{
iTempValue += (AI_averageYieldMultiplier((YieldTypes)iI) * (kCivic.getFeatureYieldChanges(iJ, iI) * (countMinCityPopOrFeatures((FeatureTypes)iJ)))) / 100;
}
In the latest patch I had removed '+ getNumCities() * 2' from this piece of code. It originally looked like this:
iTempValue += (AI_averageYieldMultiplier((YieldTypes)iI) * (kCivic.getFeatureYieldChanges(iJ, iI) * (countMinCityPopOrFeatures((FeatureTypes)iJ) + getNumCities() * 2))) / 100;
With that change, there is no crash.
Just like removing random cities, changing that line of cide still doesn't give me the cause of the crash though. It might be something seemingly unrelated. So I continued experimenting.
4) Perhaps the problem was with the countMinCityPopOrFeatures function. That's something I created myself, and rewrote too in the latest patch. If I change (countMinCityPopOrFeatures((FeatureTypes)iJ) + getNumCities() * 2) to (getNumCities() * 2), the crash goes away too. Given point 5), I don't think this function is the culprit though. For the record, I will attach the new and old version of this function in spoilers:
Spoiler :
New:
Old:
Code:
int CvPlayer::countMinCityPopOrFeatures(FeatureTypes eFeature) const
{
PROFILE_FUNC();
CvCity* pLoopCity;
CvPlot* pLoopPlot;
int iFeatureCount;
int iUsefulFeatureCount = 0;
int iLoop;
int iI;
int iPlotsNeedingImprovement = 0;
for (pLoopCity = firstCity(&iLoop); pLoopCity != NULL; pLoopCity = nextCity(&iLoop))
{
iFeatureCount = 0;
iPlotsNeedingImprovement = pLoopCity->goodHealth() - pLoopCity->badHealth(/*bNoAngry*/ false, 0);
for (iI = 0; iI < NUM_CITY_PLOTS; iI++)
{
if (iI != CITY_HOME_PLOT)
{
pLoopPlot = plotCity(pLoopCity->getX_INLINE(), pLoopCity->getY_INLINE(), iI);
if ((pLoopPlot != NULL) && (pLoopPlot->getWorkingCity() == pLoopCity))
{
if (pLoopPlot->isBeingWorked())
{
if (pLoopPlot->getFeatureType() == NO_FEATURE && pLoopPlot->getImprovementType() == NO_IMPROVEMENT)
{
iPlotsNeedingImprovement++;
}
}
}
}
}
for (iI = 0; iI < NUM_CITY_PLOTS; iI++)
{
if (iI != CITY_HOME_PLOT)
{
pLoopPlot = plotCity(pLoopCity->getX_INLINE(), pLoopCity->getY_INLINE(), iI);
if ((pLoopPlot != NULL) && (pLoopPlot->getWorkingCity() == pLoopCity))
{
if (pLoopPlot->getFeatureType() == eFeature)
{
if (pLoopPlot->isBeingWorked())
{
iUsefulFeatureCount++;
}
else if (pLoopPlot->getBonusType(getTeam()) != NO_BONUS)
{
iUsefulFeatureCount += 2;
}
else if (iFeatureCount < iPlotsNeedingImprovement)
{
iFeatureCount++;
}
}
}
}
}
iUsefulFeatureCount += iFeatureCount;
}
return iUsefulFeatureCount;
}
Code:
int CvPlayer::countMinCityPopOrFeatures(FeatureTypes eFeature) const
{
PROFILE_FUNC();
CvCity* pLoopCity;
CvPlot* pLoopPlot;
int iCount;
int iCityCount;
int iLoop;
int iI;
iCount = 0;
for (pLoopCity = firstCity(&iLoop); pLoopCity != NULL; pLoopCity = nextCity(&iLoop))
{
iCityCount = 0;
for (iI = 0; iI < NUM_CITY_PLOTS; iI++)
{
if (iI != CITY_HOME_PLOT)
{
pLoopPlot = plotCity(pLoopCity->getX_INLINE(), pLoopCity->getY_INLINE(), iI);
if ((pLoopPlot != NULL) && (pLoopPlot->getWorkingCity() == pLoopCity))
{
if (pLoopPlot->getFeatureType() == eFeature)
{
if (pLoopPlot->isBeingWorked())
{
iCount++;
iCityCount++;
}
else if (pLoopPlot->getBonusType(getTeam()) != NO_BONUS)
{
iCount += 2;
}
else if (iCityCount <= pLoopCity->getPopulation())
{
iCount++;
iCityCount++;
}
}
}
}
}
}
return iCount;
}
5) My next step was to remove the feature loop (that is: for (iJ = 0; iJ < GC.getNumFeatureInfos(); iJ++), etcetera) altogether. Then the crash DOES still occur.
I can't see any pattern:
Remove the feature loop (neither countMinCityPopOrFeatures or getNumCities): crash
Only keep countMinCityPopOrFeatures: crash
Only keep getNumCities: no crash
Have both countMinCityPopOrFeatures or getNumCities: no crash
I mean, WTF!?!
6) I figured perhaps the problem was not caused by those specific values, but perhaps by some AI switching civics. Messing around with the value of a civic might entice/prevent the AI decisions on switching civics. So I changed the code to make an AI's current civic ten times as attractive. It didn't make a difference. Then there is still a crash.
7) Sometimes a crash requires a certain random number being rolled, and making any change (like removing a city) will change the random number rolled, and thus prevent the crash. However there is no random element involved in the AI deciding what civic to pick, so I don't really see how the civic value calculations can influence random crashes.
I guess few will have read this far. -( Does anyone see some pattern in this mess?