I'm sure that bug is on Kael's to-do list, but there are a lot of things that need to be fixed. Rolling back to earlier patches to test can be quite helpful, in that you may be able to pinpoint exactly which patch introduced the problem and thus make finding the solution easier. Permanently rolling back to avoid the problems isn't helping anyone in the long run, however, because without feedback the process of locating the source of these problems will take much longer.
This particular crash is hard to track down because it doesn't seem to be happening to everyone. I've never had it happen in any of the games I've played, for example, but if I load up one of the saves someone else has produced then their game crashes for me. Is there something about my playstyle that is somehow avoiding the problem, or have I just been lucky? It's hard to say. Maybe it would be helpful for someone who has this problem to post both the crashing save and the initial save, so that someone else can try playing the game to see if their method also eventually crashes. Either way, comparing the course of different playthroughs might make something stand out as a cause.
You're absolutely correct. And just to be clear, I didn't mean to say that I've never experienced a crash.[...] and almost every game crashes at some point.
/************************************************************************************************/
/* UNOFFICIAL_PATCH 06/14/09 Maniac & jdog5000 */
/* */
/* */
/************************************************************************************************/
/* original bts code
CvEventReporter::getInstance().cityAcquiredAndKept(GC.getGameINLINE().getActivePlayer(), pCity);
*/
CvEventReporter::getInstance().cityAcquiredAndKept(getID(), pCity);
/************************************************************************************************/
/* UNOFFICIAL_PATCH END */
/************************************************************************************************/
[COLOR="SeaGreen"]/*************************************************************************************************/
/** BETTER AI (Block some Units from attacking at low odds) Sephi **/
/** **/
/** **/
/*************************************************************************************************/[/COLOR]
if (!GET_PLAYER(pLoopUnit->getOwnerINLINE()).isHuman())
{
if (pLoopUnit->AI_getUnitAIType()==UNITAI_WARWIZARD)
{
if (iOdds<95)
{
[COLOR="Red"] iValue=0;[/COLOR]
}
}
if (pLoopUnit->AI_getUnitAIType()==UNITAI_HERO)
{
if (iOdds<85)
{
[COLOR="Red"] iValue=0;[/COLOR]
}
}
}
[COLOR="SeaGreen"]/*************************************************************************************************/
/** END **/
/*************************************************************************************************/[/COLOR]
[COLOR="blue"]FAssertMsg(iValue > 0, "iValue is expected to be greater than 0");[/COLOR]
/*************************************************************************************************/
/** BETTER AI (Block some Units from attacking at low odds) Sephi **/
/** **/
/** **/
/*************************************************************************************************/
if (!GET_PLAYER(pLoopUnit->getOwnerINLINE()).isHuman())
{
if (pLoopUnit->AI_getUnitAIType()==UNITAI_WARWIZARD)
{
if (iOdds<95)
{
iValue=0; //Need to put the min to 1 to prevent WoC
}
}
if (pLoopUnit->AI_getUnitAIType()==UNITAI_HERO)
{
if (iOdds<85)
{
iValue=0;
}
}
if (pLoopUnit->getLevel()>4 && iOdds<95)
{
iValue/=2;
}
}
iValue=std::max(1,iValue);
/*************************************************************************************************/
/** END **/
/*************************************************************************************************/
if (getUnitClassCountPlusMaking(GC.getReligionInfo(getFavoriteReligion()).getReligionHero2())>0)
{
valid=false;
}
void CvPlayer::AI_doFavoriteReligion()
{
for (int iI = 0; iI < GC.getNumTraitInfos(); ++iI)
{
if (hasTrait((TraitTypes)iI))
{
if(GC.getTraitInfo((TraitTypes)iI).isAgnostic())
{
return;
}
}
}
//Pick a Favorite Religion
if (getFavoriteReligion()==NO_RELIGION)
{
for (int i=0;i<GC.getNumReligionInfos();i++)
{
if (GC.getGameINLINE().getSorenRandNum(100,"Choose Religion")<GC.getLeaderHeadInfo(getLeaderType()).getReligionWeightModifier(i))
{
setFavoriteReligion((ReligionTypes)i);
break;
}
}
//If still have none, pick randomly
int hack=0;
while (getFavoriteReligion()==NO_RELIGION)
{
ReligionTypes newReligion=(ReligionTypes)GC.getGameINLINE().getSorenRandNum(GC.getNumReligionInfos(),"Choose Religion");
if (GC.getLeaderHeadInfo(getLeaderType()).getReligionWeightModifier(newReligion)>=0)
{
setFavoriteReligion(newReligion);
}
hack++;
if (hack==30)
{
break;
}
}
}
//Convert to Favorite Religion if possible
if (getFavoriteReligion()!=NO_RELIGION)
{
if(canConvert(getFavoriteReligion()))
{
convert(getFavoriteReligion());
}
}
//Choose new Religion for Opportunists
if (GC.getLeaderHeadInfo(getLeaderType()).isReligionOpportunist() && getFavoriteReligion()!=NO_RELIGION)
{
bool valid=true;
if (GC.getReligionInfo(getFavoriteReligion()).getReligionHero1()!=NO_UNITCLASS)
{
if (GC.getGameINLINE().getUnitClassCreatedCount(GC.getReligionInfo(getFavoriteReligion()).getReligionHero1())==0)
{
valid=false;
}
}
if (GC.getReligionInfo(getFavoriteReligion()).getReligionHero2()!=NO_UNITCLASS)
{
if (GC.getGameINLINE().getUnitClassCreatedCount(GC.getReligionInfo(getFavoriteReligion()).getReligionHero2())==0)
{
valid=false;
}
}
if (GC.getReligionInfo(getFavoriteReligion()).getReligionHero1()!=NO_UNITCLASS
&& getUnitClassCountPlusMaking(GC.getReligionInfo(getFavoriteReligion()).getReligionHero1())>0)
{
valid=false;
}
if (GC.getReligionInfo(getFavoriteReligion()).getReligionHero2()!=NO_UNITCLASS
&& getUnitClassCountPlusMaking(GC.getReligionInfo(getFavoriteReligion()).getReligionHero2())>0)
{
valid=false;
}
if (valid)
{
for (int i=0;i<GC.getNumReligionInfos();i++)
{
if (((GC.getReligionInfo(getFavoriteReligion()).getReligionHero1()!=NO_UNITCLASS
&& GC.getGameINLINE().getUnitClassCreatedCount(GC.getReligionInfo((ReligionTypes)i).getReligionHero1())==0))
||((GC.getReligionInfo(getFavoriteReligion()).getReligionHero2()!=NO_UNITCLASS && GC.getGameINLINE().getUnitClassCreatedCount(GC.getReligionInfo((ReligionTypes)i).getReligionHero2())==0)))
{
if (GC.getLeaderHeadInfo(getLeaderType()).getReligionWeightModifier((ReligionTypes)i)>=0)
{
setFavoriteReligion((ReligionTypes)i);
}
break;
}
}
}
}
return;
}
1.) a few things got broke in the Merge from Wildmana to FFH and this is one of them (I guess Kael forgot the XML part of it). I have completly rewritten it (was just cheap temporary python thing anyway to try out a few things), so can't give you an easy fix. But I think if you block in the DLL the python callback where they are used and instead use the standard BTS promotion selection AI_bestPromotion or whatever it is you should be fine (and the BTS function will still be better than a function where most of it is missing).
2. yeah, that was also one of the first things I caught with a debug DLL.
Things to do:
...
. I want to switch the "Wrath" armageddon event (AC 90) to make all the effected units Always Hostile so they can fight with your allied neighbors.