Single Player bugs and crashes v35 plus (SVN) - After the 18th of August 2014

Thanks Thunderbrd. Something I like to do these small, fast game to explore the tech tree. I was able to make it work by reverting to an older version.

If it's relevant, I am playing on a 64 bit Windows 7 machine.

Since I don't see others with similar problems, I'll try with the latest version and see what quirky settings I might have that caused problem.
 
This bug happens sometimes now, look screenshot message text.
 

Attachments

  • Civ4ScreenShot0006.JPG
    Civ4ScreenShot0006.JPG
    385.9 KB · Views: 89
Thanks Thunderbrd. Something I like to do these small, fast game to explore the tech tree. I was able to make it work by reverting to an older version.

If it's relevant, I am playing on a 64 bit Windows 7 machine.

Since I don't see others with similar problems, I'll try with the latest version and see what quirky settings I might have that caused problem.

A minidump might've been able to see what happened specifically there. It MIGHT not be a repeatable crash. But a mini must be evaluated on a codeset that has been completely unaltered so if I've been making any recent or current changes it's hard to get a mini to be revealing.
 
I've noticed a persistent bug over a number of SVN updates where at a particular point (starting from Prehistoric, normally occurring in Industrial or Modern), my cities will adapt the "Some buildings are upsetting us!" values twice, which normally plunges the productivity of my empire into the toilet and brings an end to the game.

Spoiler :
11lk5ra.png


Also, during my last game I've had a very peculiar error where after another civilization became a vassal state (due to relative strength, not capitulation), one city in particular would every few turns ask to join their empire - even though the culture was 100% my civ and the other civ was on a completely different continent.

Spoiler :
5lx6ax.png


Spoiler :
wlf11e.png


Here is the save.

http://www.filedropper.com/testbc-0166-winter
 
Subdued Moose to build moos hunter camp needs deer and bison in city vicinity? Maybe remove bison. Deer hunter camp only needs deer in city vicinity.

I suspect this is a hold over from before we had Moose in game. It should only require deer in vicinity now. I will fix.

A reminder in case forgotten: TERRAIN_SNOW is never generated in the perfectMongoose_mapscript.

@DH: would you know how to fix this long lasting issue?

That should have been done by whoever did the conversion of the map scripts. I have not delved into them myself only adding some C2C to the post map script area. I'll see what I can do.

This bug happens sometimes now, look screenshot message text.

That error should have produced more detail in the PythonErr.log file. Posting that will probably help in identifying the problem. The PythonErr2.log may also help in identifying the start up error you are getting with Revolutions. Both files get overwritten when you start a new game.
 
I've noticed a persistent bug over a number of SVN updates where at a particular point (starting from Prehistoric, normally occurring in Industrial or Modern), my cities will adapt the "Some buildings are upsetting us!" values twice, which normally plunges the productivity of my empire into the toilet and brings an end to the game.

I think this is related to a bug I reported several times, namely that a CONQUERED CITY doesn't reset its economic production values to zero upon conquest, but gets the benefits and penalties of buildings a second time, leading to all kinds of stuff (tech, money, resources produced, XP for new units etc etc etc etc etc) being counted double. If you add up all the correct values of buildings by hand they are much lower than what the city screen numbers show. And this is not just a display error; you actually get the bugged benefits.

I'm not sure if the AI conquers a city from another AI gets the same benefits, but it is likely. In fact if a city changes ownership more than once, the buggy benefits may add up several times, leading to crazy amounts of production.

This is a major, major balance problem, it leads to a massive snowball effect for conquering civs. Every time you conquer a city, you get 2 cities worth of production capacity but only 1 more city worth of maintenance. It has been around since at least version 33 (when I started playing this mod).

Pressing shift-CTRL-T (recalculate everything) solves it temporarily. Until the next city is conquered. To play absolutely fair, you should shift-CTRL-T every time a city is conquered by anyone anywhere in the world (including you).

Also, buildings like stone tools maker in a conquered city give production based on the tech level of the original city owning civ. When you yourself tech up, the mutations of the new techs are still added, leading to crazy stuff like stone tools maker giving negative hammer production in certain cities.
 
I've noticed a persistent bug over a number of SVN updates where at a particular point (starting from Prehistoric, normally occurring in Industrial or Modern), my cities will adapt the "Some buildings are upsetting us!" values twice, which normally plunges the productivity of my empire into the toilet and brings an end to the game.

Spoiler :
11lk5ra.png


Also, during my last game I've had a very peculiar error where after another civilization became a vassal state (due to relative strength, not capitulation), one city in particular would every few turns ask to join their empire - even though the culture was 100% my civ and the other civ was on a completely different continent.

Spoiler :
5lx6ax.png


wlf11e.png


Here is the save.

http://www.filedropper.com/testbc-0166-winter

Can YOU pls put these in a spoiler, it is taking up too much space and WIDTH, thx . . .SO
 
I think this is related to a bug I reported several times, namely that a CONQUERED CITY doesn't reset its economic production values to zero upon conquest, but gets the benefits and penalties of buildings a second time, leading to all kinds of stuff (tech, money, resources produced, XP for new units etc etc etc etc etc) being counted double. If you add up all the correct values of buildings by hand they are much lower than what the city screen numbers show. And this is not just a display error; you actually get the bugged benefits.

I'm not sure if the AI conquers a city from another AI gets the same benefits, but it is likely. In fact if a city changes ownership more than once, the buggy benefits may add up several times, leading to crazy amounts of production.

This is a major, major balance problem, it leads to a massive snowball effect for conquering civs. Every time you conquer a city, you get 2 cities worth of production capacity but only 1 more city worth of maintenance. It has been around since at least version 33 (when I started playing this mod).

Pressing shift-CTRL-T (recalculate everything) solves it temporarily. Until the next city is conquered. To play absolutely fair, you should shift-CTRL-T every time a city is conquered by anyone anywhere in the world (including you).

Also, buildings like stone tools maker in a conquered city give production based on the tech level of the original city owning civ. When you yourself tech up, the mutations of the new techs are still added, leading to crazy stuff like stone tools maker giving negative hammer production in certain cities.
That's still an issue? That's important enough to address before v36 and shouldn't be too difficult to call for a local recalculation on any city just conquered. Probably already does... just out of order somewhere.

Interesting effect... wasn't aware of it. You've explained it quite well this time.

EDIT: Wow... it's complicated I'll give you that. Entirely possible something is skewed. It will take a fairly major auditing process to make sure its resolved properly.
 
Can YOU pls put these in a spoiler, it is taking up too much space and WIDTH, thx . . .SO

My bad, sorry.

Noriad2 said:
I think this is related to a bug I reported several times, namely that a CONQUERED CITY doesn't reset its economic production values to zero upon conquest, but gets the benefits and penalties of buildings a second time, leading to all kinds of stuff (tech, money, resources produced, XP for new units etc etc etc etc etc) being counted double. If you add up all the correct values of buildings by hand they are much lower than what the city screen numbers show. And this is not just a display error; you actually get the bugged benefits.

In this case, the city wasn't conquered by anyone. This bug appears to happen with all the settled cities in my empire, and I am not holding any foreign ones.
 
In this case, the city wasn't conquered by anyone. This bug appears to happen with all the cities in my empire, and I am not holding any foreign ones.

It's certainly strange. I'll take a look at the code to see if its visible on a readthrough. It's possible there's 2 different tallies taking place there, probable actually, just both using the same text tag. If nothing else I can see if I can make it less ambiguous. But it could indeed be a true bug in the calculation somewhere. Happiness/Unhappiness/Health/Unhealth tallies have been needing a thorough audit for some time now. Not a fun task at all.
 
Can any coders spot the errors Noriad is pointing at in his post above? (Part I)
Spoiler :
Code:
void CvPlayer::acquireCity(CvCity* pOldCity, bool bConquest, bool bTrade, bool bUpdatePlotGroups)
{
	PROFILE_FUNC();

/************************************************************************************************/
/* REVOLUTION_MOD                         01/01/08                                jdog5000      */
/*                                                                                              */
/* Copy over city data                                                                          */
/************************************************************************************************/
	std::string scriptData;
	int iRevIdx;
	int iLocalRevIdx;
/************************************************************************************************/
/* REVOLUTION_MOD                          END                                                  */
/************************************************************************************************/

	CLLNode<IDInfo>* pUnitNode;
	CvCity* pNewCity;
	CvUnit* pLoopUnit;
	CvPlot* pCityPlot;
	CvPlot* pLoopPlot;
	bool* pabHasReligion;
	bool* pabHolyCity;
	bool* pabHasCorporation;
	bool* pabHeadquarters;
	int* paiNumRealBuilding;
	int* paiBuildingOriginalOwner;
	int* paiBuildingOriginalTime;
	CvWString szBuffer;
	CvWString szName;
	bool abEverOwned[MAX_PLAYERS];
	int aiCulture[MAX_PLAYERS];
	PlayerTypes eOldOwner;
	PlayerTypes eOriginalOwner;
	PlayerTypes eHighestCulturePlayer;
	BuildingTypes eBuilding;
	bool bRecapture;
	bool bRaze;
	bool bGift;
	int iRange;
	int iCaptureGold;
	int iGameTurnFounded;
	int iPopulation;
	int iHighestPopulation;
	int iHurryAngerTimer;
	int iConscriptAngerTimer;
	int iDefyResolutionAngerTimer;
	int iOccupationTimer;
	int iTeamCulturePercent;
	int iDamage;
	int iDX, iDY;
	int iI;
	CLinkList<IDInfo> oldUnits;
	std::vector<int> aeFreeSpecialists;
	CvPlotGroup* originalTradeNetworkConnectivity[MAX_PLAYERS];

/************************************************************************************************/
/* Afforess	                  Start		 02/15/10                                               */
/*                                                                                              */
/*                                                                                              */
/************************************************************************************************/
	int iOccupationRange = 0;
/************************************************************************************************/
/* Afforess	                     END                                                            */
/************************************************************************************************/
/************************************************************************************************/
/* Afforess	                  Start		 06/14/10                                               */
/*                                                                                              */
/*                                                                                              */
/************************************************************************************************/
	int iOccupationTimeModifier = 100;
	for (iI = 0; iI < GC.getNumBuildingInfos(); iI++)
	{
		if (pOldCity->getNumRealBuilding((BuildingTypes)iI) > 0)
		{
			if (GC.getBuildingInfo((BuildingTypes)iI).getOccupationTimeModifier() != 0)
			{
				iOccupationTimeModifier += GC.getBuildingInfo((BuildingTypes)iI).getOccupationTimeModifier();
			}
		}
	}
/************************************************************************************************/
/* Afforess	                     END                                                            */
/************************************************************************************************/
	pCityPlot = pOldCity->plot();
	eOldOwner = pOldCity->getOwnerINLINE();

	//	Whose trade networks was this city relevant to prior to ownership change
	if ( bUpdatePlotGroups )
	{
		for(int iI = 0; iI < MAX_PLAYERS; iI++)
		{
			originalTradeNetworkConnectivity[iI] = GET_PLAYER((PlayerTypes)iI).isAlive() ? pCityPlot->getPlotGroup((PlayerTypes)iI) : NULL;
		}
	}
	
	pUnitNode = pCityPlot->headUnitNode();

	while (pUnitNode != NULL)
	{
		oldUnits.insertAtEnd(pUnitNode->m_data);
		pUnitNode = pCityPlot->nextUnitNode(pUnitNode);
	}

	pUnitNode = oldUnits.head();

	while (pUnitNode != NULL)
	{
		pLoopUnit = ::getUnit(pUnitNode->m_data);
		pUnitNode = oldUnits.next(pUnitNode);

		if (pLoopUnit && pLoopUnit->getTeam() != getTeam())
		{
			if (pLoopUnit->getDomainType() == DOMAIN_IMMOBILE)
			{
				pLoopUnit->kill(false, getID());
			}
		}
	}
/************************************************************************************************/
/* Afforess	                  Start		 07/21/10                                               */
/*                                                                                              */
/*                                                                                              */
/************************************************************************************************/
	iRange = pOldCity->getMaxCultureLevelAmongPlayers();

	iOccupationRange = iRange;

	if (hasFixedBorders())
	{
		pOldCity->clearCultureDistanceCache();
		for (iDX = -(iRange); iDX <= iRange; iDX++)
		{
			for (iDY = -(iRange); iDY <= iRange; iDY++)
			{
				if (pOldCity->cultureDistance(iDX, iDY) <= iRange)
				{
					pLoopPlot = plotXY(pOldCity->getX_INLINE(),pOldCity-> getY_INLINE(), iDX, iDY);

					if (pLoopPlot != NULL)
					{
						if (!pLoopPlot->isCity())	
						{
							if ((pLoopPlot->getOwnerINLINE() == pOldCity->getOwnerINLINE()) || (pLoopPlot->getOwnerINLINE() == NO_PLAYER))
							{
								bool bCultureLevelFound = false;
								bool bDoClaim = false;

								for (int iJ = 0; iJ < GC.getNumCultureLevelInfos(); ++iJ)
								{
									int iNumCitiesForRange = pLoopPlot->getCultureRangeCities(pOldCity->getOwnerINLINE(), iJ);
									
									// Occupy the tile if it is within the city's culture range, but not within any other city's range at the same or closer distance 
									if ((iNumCitiesForRange == 1) && ((pOldCity->getCultureLevel() >= iJ) && (pOldCity->cultureDistance(iDX, iDY) == iJ))) 
									{
										bDoClaim = true;
									}
									
									if (iNumCitiesForRange > 0) 
									{
										bCultureLevelFound = true;
										break;
									} 
								}

								// Occupy the tile if it is NOT within the city's culture range, but is within occupation range 
								if (!bCultureLevelFound)
								{
									if (pOldCity->cultureDistance(iDX, iDY) <= pOldCity->getOccupationCultureLevel())
									{
										bDoClaim = true;
									}
								}

								if (bDoClaim && pLoopPlot->isPotentialCityWorkForArea(pOldCity->area()))
								{							
									pLoopPlot->setClaimingOwner(getID());
									pLoopPlot->setForceUnownedTimer(1);
								}								
							}
						}
					}
				}
			}
		}
	}
	if (bConquest && !hasFixedBorders())
/************************************************************************************************/
/* Afforess	                     END                                                            */
/************************************************************************************************/
	{
		iRange = pOldCity->getCultureLevel();

		for (iDX = -(iRange); iDX <= iRange; iDX++)
		{
			for (iDY = -(iRange); iDY <= iRange; iDY++)
			{
/************************************************************************************************/
/* Afforess	                  Start		 02/15/10                                               */
/*                                                                                              */
/*                                                                                              */
/************************************************************************************************/
				if ((pOldCity->cultureDistance(iDX, iDY) <= iRange) && (pOldCity->cultureDistance(iDX, iDY) > 1))
/************************************************************************************************/
/* Afforess	                     END                                                            */
/************************************************************************************************/
				{
					pLoopPlot = plotXY(pOldCity->getX_INLINE(),pOldCity-> getY_INLINE(), iDX, iDY);

					if (pLoopPlot != NULL)
					{
						if (pLoopPlot->getOwnerINLINE() == pOldCity->getOwnerINLINE())	
						{
							if (pLoopPlot->getNumCultureRangeCities(pOldCity->getOwnerINLINE()) == 1)
							{
								bool bForceUnowned = false;

								for (iI = 0; iI < MAX_PLAYERS; iI++)
								{
									if (GET_PLAYER((PlayerTypes)iI).isAlive())
									{
										if ((GET_PLAYER((PlayerTypes)iI).getTeam() != getTeam()) && (GET_PLAYER((PlayerTypes)iI).getTeam() != pOldCity->getTeam()))
										{
											if (pLoopPlot->getNumCultureRangeCities((PlayerTypes)iI) > 0)
											{
												bForceUnowned = true;
												break;
											}
										}
									}
								}

								if (bForceUnowned)
								{
									pLoopPlot->setForceUnownedTimer(GC.getDefineINT("FORCE_UNOWNED_CITY_TIMER"));
								}
							}
						}
					}
				}
			}
		}
	}

	if (pOldCity->getOriginalOwner() == pOldCity->getOwnerINLINE())
	{
		GET_PLAYER(pOldCity->getOriginalOwner()).changeCitiesLost(1);
	}
/************************************************************************************************/
/* REVOLUTION_MOD                         05/30/08                                jdog5000      */
/*                                                                                              */
/* For BarbarianCiv                                                                             */
/************************************************************************************************/
	// Added new BarbCiv specfic circumstance for counting a city as lost
	else if( !GC.getGame().isOption(GAMEOPTION_NO_BARBARIAN_CIV) && pOldCity->isCapital() && pOldCity->getOriginalOwner() == GC.getBARBARIAN_PLAYER() )
	{
		GET_PLAYER(pOldCity->getOwnerINLINE()).changeCitiesLost(1);
	}
/************************************************************************************************/
/* REVOLUTION_MOD                          END                                                  */
/************************************************************************************************/
	else if (pOldCity->getOriginalOwner() == getID())
	{
		GET_PLAYER(pOldCity->getOriginalOwner()).changeCitiesLost(-1);
	}

	if (bConquest)
	{
		{
			MEMORY_TRACK_EXEMPT();

			szBuffer = gDLL->getText("TXT_KEY_MISC_CAPTURED_CITY", pOldCity->getNameKey()).GetCString();
			AddDLLMessage(getID(), true, GC.getEVENT_MESSAGE_TIME(), szBuffer, "AS2D_CITYCAPTURE", MESSAGE_TYPE_MAJOR_EVENT, ARTFILEMGR.getInterfaceArtInfo("WORLDBUILDER_CITY_EDIT")->getPath(), (ColorTypes)GC.getInfoTypeForString("COLOR_GREEN"), pOldCity->getX_INLINE(), pOldCity->getY_INLINE(), true, true);
		}
		szName.Format(L"%s (%s)", pOldCity->getName().GetCString(), GET_PLAYER(pOldCity->getOwnerINLINE()).getName());

		for (iI = 0; iI < MAX_PLAYERS; iI++)
		{
			if (GET_PLAYER((PlayerTypes)iI).isAlive())
			{
				if (iI != getID())
				{
					MEMORY_TRACK_EXEMPT();

					if (pOldCity->isRevealed(GET_PLAYER((PlayerTypes)iI).getTeam(), false))
					{
						szBuffer = gDLL->getText("TXT_KEY_MISC_CITY_CAPTURED_BY", szName.GetCString(), getCivilizationDescriptionKey());
						AddDLLMessage(((PlayerTypes)iI), false, GC.getEVENT_MESSAGE_TIME(), szBuffer, "AS2D_CITYCAPTURED", MESSAGE_TYPE_MAJOR_EVENT, ARTFILEMGR.getInterfaceArtInfo("WORLDBUILDER_CITY_EDIT")->getPath(), (ColorTypes)GC.getInfoTypeForString("COLOR_RED"), pOldCity->getX_INLINE(), pOldCity->getY_INLINE(), true, true);
					}
				/************************************************************************************************/
				/* Afforess	                  Start		 12/9/09                                                */
				/*                                                                                              */
				/*                                                                                              */
				/************************************************************************************************/
					else if (GET_TEAM(GET_PLAYER((PlayerTypes)iI).getTeam()).isHasEmbassy(getTeam()))
					{
						szBuffer = gDLL->getText("TXT_KEY_MISC_CITY_CAPTURED_BY", szName.GetCString(), getCivilizationDescriptionKey());
						AddDLLMessage(((PlayerTypes)iI), false, GC.getEVENT_MESSAGE_TIME(), szBuffer, "AS2D_CITYCAPTURED", MESSAGE_TYPE_MAJOR_EVENT, NULL, (ColorTypes)GC.getInfoTypeForString("COLOR_RED"));
					}
				/************************************************************************************************/
				/* Afforess	                     END                                                            */
				/************************************************************************************************/
				}
			}
		}

		szBuffer = gDLL->getText("TXT_KEY_MISC_CITY_WAS_CAPTURED_BY", szName.GetCString(), getCivilizationDescriptionKey());
		GC.getGameINLINE().addReplayMessage(REPLAY_MESSAGE_MAJOR_EVENT, getID(), szBuffer, pOldCity->getX_INLINE(), pOldCity->getY_INLINE(), (ColorTypes)GC.getInfoTypeForString("COLOR_WARNING_TEXT"));
	}

	iCaptureGold = 0;

	if (bConquest)
	{
		PYTHON_ACCESS_LOCK_SCOPE

		long lCaptureGold;
		// Use python to determine city capture gold amounts...
		lCaptureGold = 0;

		CyCity* pyOldCity = new CyCity(pOldCity);

		CyArgsList argsList;
		argsList.add(gDLL->getPythonIFace()->makePythonObject(pyOldCity));	// pass in plot class
		
		PYTHON_CALL_FUNCTION4(__FUNCTION__, PYGameModule, "doCityCaptureGold", argsList.makeFunctionArgs(),&lCaptureGold);

		delete pyOldCity;	// python fxn must not hold on to this pointer 

		iCaptureGold = (int)lCaptureGold;
	}

	changeGold(iCaptureGold);

	pabHasReligion = new bool[GC.getNumReligionInfos()];
	pabHolyCity = new bool[GC.getNumReligionInfos()];
	pabHasCorporation = new bool[GC.getNumCorporationInfos()];
	pabHeadquarters = new bool[GC.getNumCorporationInfos()];
	paiNumRealBuilding = new int[GC.getNumBuildingInfos()];
	paiBuildingOriginalOwner = new int[GC.getNumBuildingInfos()];
	paiBuildingOriginalTime = new int[GC.getNumBuildingInfos()];

	for (iI = 0; iI < GC.getNumVoteSourceInfos(); ++iI)
	{
		pOldCity->processVoteSourceBonus((VoteSourceTypes)iI, false);
	}

	//	Koshling - need to remove bonuses due io old owner's trade network
	//	else it can feed into yield modifiers which are then incorrectly
	//	copied over to the new owner
	for (iI = 0; iI < GC.getNumBonusInfos(); ++iI)
	{
		if (pOldCity->hasBonus((BonusTypes)iI))
		{
			pOldCity->processBonus((BonusTypes)iI, -1);
		}
	}

	eOriginalOwner = pOldCity->getOriginalOwner();
	eHighestCulturePlayer = pOldCity->findHighestCulture();
	iGameTurnFounded = pOldCity->getGameTurnFounded();
	iPopulation = pOldCity->getPopulation();
	iHighestPopulation = pOldCity->getHighestPopulation();
	iHurryAngerTimer = pOldCity->getHurryAngerTimer();
	iConscriptAngerTimer = pOldCity->getConscriptAngerTimer();
	iDefyResolutionAngerTimer = pOldCity->getDefyResolutionAngerTimer();
	iOccupationTimer = pOldCity->getOccupationTimer();
	szName = pOldCity->getNameKey();
/************************************************************************************************/
/* REVOLUTION_MOD                         01/01/08                                jdog5000      */
/*                                                                                              */
/*                                                                                              */
/************************************************************************************************/
	scriptData = pOldCity->getScriptData();
	iRevIdx = pOldCity->getRevolutionIndex();
	iLocalRevIdx = pOldCity->getLocalRevIndex();
/************************************************************************************************/
/* REVOLUTION_MOD                          END                                                  */
/************************************************************************************************/
	iDamage = pOldCity->getDefenseDamage();
	int iOldCityId = pOldCity->getID();

/************************************************************************************************/
/* Afforess	                  Start		 01/12/10                                               */
/*                                                                                              */
/*                                                                                              */
/************************************************************************************************/
	int iCiv = pOldCity->getCivilizationType();
	if (pOldCity->isBarbarian())
	{
	    iCiv = NO_CIVILIZATION;
	}
/************************************************************************************************/
/* Afforess	                     END                                                            */
/************************************************************************************************/

	
	for (iI = 0; iI < GC.getNumSpecialistInfos(); ++iI)
	{
		aeFreeSpecialists.push_back(pOldCity->getAddedFreeSpecialistCount((SpecialistTypes)iI));
	}

	for (iI = 0; iI < MAX_PLAYERS; iI++)
	{
		abEverOwned[iI] = pOldCity->isEverOwned((PlayerTypes)iI);
		aiCulture[iI] = pOldCity->getCultureTimes100((PlayerTypes)iI);
	}

	abEverOwned[getID()] = true;

	for (iI = 0; iI < GC.getNumReligionInfos(); iI++)
	{
		pabHasReligion[iI] = pOldCity->isHasReligion((ReligionTypes)iI);
		pabHolyCity[iI] = pOldCity->isHolyCity((ReligionTypes)iI);
	}

	for (iI = 0; iI < GC.getNumCorporationInfos(); iI++)
	{
		pabHasCorporation[iI] = pOldCity->isHasCorporation((CorporationTypes)iI);
		pabHeadquarters[iI] = pOldCity->isHeadquarters((CorporationTypes)iI);
	}

	for (iI = 0; iI < GC.getNumBuildingInfos(); iI++)
	{
		paiNumRealBuilding[iI] = pOldCity->getNumRealBuilding((BuildingTypes)iI);
		paiBuildingOriginalOwner[iI] = pOldCity->getBuildingOriginalOwner((BuildingTypes)iI);
		paiBuildingOriginalTime[iI] = pOldCity->getBuildingOriginalTime((BuildingTypes)iI);
	}

	BuildingChangeArray aBuildingHappyChange;
	BuildingChangeArray aBuildingHealthChange;
	for (iI = 0; iI < GC.getNumBuildingClassInfos(); ++iI)
	{
		int iChange = pOldCity->getBuildingHappyChange((BuildingClassTypes)iI);
		if (0 != iChange)
		{
			aBuildingHappyChange.push_back(std::make_pair((BuildingClassTypes)iI, iChange));
		}

		iChange = pOldCity->getBuildingHealthChange((BuildingClassTypes)iI);
		if (0 != iChange)
		{
			aBuildingHealthChange.push_back(std::make_pair((BuildingClassTypes)iI, iChange));
		}
	}

	bRecapture = ((eHighestCulturePlayer != NO_PLAYER) ? (GET_PLAYER(eHighestCulturePlayer).getTeam() == getTeam()) : false);

	pOldCity->kill(false, false);

	if (bTrade)
	{
		for (iDX = -1; iDX <= 1; iDX++)
		{
			for (iDY = -1; iDY <= 1; iDY++)
			{
				pLoopPlot	= plotXY(pCityPlot->getX_INLINE(), pCityPlot->getY_INLINE(), iDX, iDY);

				if (pLoopPlot != NULL)
				{
					pLoopPlot->setCulture(eOldOwner, 0, false, false);
				}
			}
		}
	}
 
Part II
Spoiler :
Code:
	pNewCity = initCity(pCityPlot->getX_INLINE(), pCityPlot->getY_INLINE(), !bConquest, false);

	FAssertMsg(pNewCity != NULL, "NewCity is not assigned a valid value");

	pNewCity->setPreviousOwner(eOldOwner);
	pNewCity->setOriginalOwner(eOriginalOwner);
	pNewCity->setGameTurnFounded(iGameTurnFounded);
	pNewCity->setPopulation((bConquest && !bRecapture) ? std::max(1, (iPopulation - 1)) : iPopulation);
	pNewCity->setHighestPopulation(iHighestPopulation);
	pNewCity->setName(szName);
	pNewCity->setNeverLost(false);
	pNewCity->changeDefenseDamage(iDamage);
	
/************************************************************************************************/
/* Afforess	                  Start		 01/12/10                                               */
/*                                                                                              */
/*                                                                                              */
/************************************************************************************************/
	if (iCiv != NO_CIVILIZATION)
    {
        pNewCity->setCivilizationType(iCiv);
    }
/************************************************************************************************/
/* Afforess	                     END                                                            */
/************************************************************************************************/

/************************************************************************************************/
/* REVOLUTION_MOD                         01/01/08                                jdog5000      */
/*                                                                                              */
/*                                                                                              */
/************************************************************************************************/
	pNewCity->setScriptData(scriptData);
	pNewCity->setRevolutionIndex( iRevIdx );
	pNewCity->setLocalRevIndex( iLocalRevIdx );
/************************************************************************************************/
/* REVOLUTION_MOD                          END                                                  */
/************************************************************************************************/

	for (iI = 0; iI < MAX_PLAYERS; iI++)
	{
		pNewCity->setEverOwned(((PlayerTypes)iI), abEverOwned[iI]);
		pNewCity->setCultureTimes100(((PlayerTypes)iI), aiCulture[iI], false, false);
	}

	CvCivilizationInfo& kCivilizationInfo = GC.getCivilizationInfo(getCivilizationType());

	for (iI = 0; iI < GC.getNumBuildingInfos(); iI++)
	{
		int iNum = 0;

		if (paiNumRealBuilding[iI] > 0)
		{
			BuildingClassTypes eBuildingClass = (BuildingClassTypes)GC.getBuildingInfo((BuildingTypes)iI).getBuildingClassType();
/************************************************************************************************/
/* Afforess	                  Start		 02/03/10                                              */
/*                                                                                              */
/*   Assimilation Bug Fix                                                                       */
/************************************************************************************************/
			if ((::isWorldWonderClass(eBuildingClass)) || (GC.getGameINLINE().isOption(GAMEOPTION_ASSIMILATION)))
			{
				eBuilding = (BuildingTypes)iI;
/************************************************************************************************/
/* Afforess	                     END                                                            */
/************************************************************************************************/
			}
			else
			{			
				eBuilding = (BuildingTypes)kCivilizationInfo.getCivilizationBuildings(eBuildingClass);
			}

			if (eBuilding != NO_BUILDING)
			{
				if (bTrade || !(GC.getBuildingInfo((BuildingTypes)iI).isNeverCapture()))
				{
					if (!isProductionMaxedBuildingClass(((BuildingClassTypes)(GC.getBuildingInfo(eBuilding).getBuildingClassType())), true))
					{
						if (pNewCity->isValidBuildingLocation(eBuilding))
						{
							if (!bConquest || bRecapture || GC.getGameINLINE().getSorenRandNum(100, "Capture Probability") < GC.getBuildingInfo((BuildingTypes)iI).getConquestProbability())
							{
								iNum += paiNumRealBuilding[iI];
							}
						}
					}
				}

				pNewCity->setNumRealBuildingTimed(eBuilding, std::min(pNewCity->getNumRealBuilding(eBuilding) + iNum, GC.getCITY_MAX_NUM_BUILDINGS()), false, ((PlayerTypes)(paiBuildingOriginalOwner[iI])), paiBuildingOriginalTime[iI]);
			}
		}
	}

	for (BuildingChangeArray::iterator it = aBuildingHappyChange.begin(); it != aBuildingHappyChange.end(); ++it)
	{
		pNewCity->setBuildingHappyChange((*it).first, (*it).second);
	}

	for (BuildingChangeArray::iterator it = aBuildingHealthChange.begin(); it != aBuildingHealthChange.end(); ++it)
	{
		pNewCity->setBuildingHealthChange((*it).first, (*it).second);
	}

	for (iI = 0; iI < GC.getNumSpecialistInfos(); ++iI)
	{
		pNewCity->changeFreeSpecialistCount((SpecialistTypes)iI, aeFreeSpecialists[iI], true);
	}

	for (iI = 0; iI < GC.getNumReligionInfos(); iI++)
	{
		if (pabHasReligion[iI])
		{
			pNewCity->setHasReligion(((ReligionTypes)iI), true, false, true);
		}

		if (pabHolyCity[iI])
		{
			GC.getGameINLINE().setHolyCity(((ReligionTypes)iI), pNewCity, false);
			// Sanguo Mod Performance start, added by poyuzhe 07.26.09
			for (int iJ = 0; iJ < GC.getMAX_PLAYERS(); iJ++)
			{
				if (GET_PLAYER((PlayerTypes)iJ).isAlive() && GET_PLAYER((PlayerTypes)iI).getStateReligion() == (ReligionTypes)iI)
				{
					GET_PLAYER(getID()).AI_invalidateAttitudeCache((PlayerTypes)iJ);
					GET_PLAYER((PlayerTypes)iJ).AI_invalidateAttitudeCache(getID());
				}
			}
			// Sanguo Mod Performance, end
		}
	}
/************************************************************************************************/
/* RevDCM	                  Start		 12/9/09                                                */
/*                                                                                              */
/* Inquisitions                                                                                 */
/************************************************************************************************/
	if(!(GET_PLAYER(eOldOwner).isHuman()))
	{
		GET_PLAYER(eOldOwner).AI_setHasInquisitionTarget();
	}
	if(!(GET_PLAYER(getID()).isHuman()))
	{
		GET_PLAYER(getID()).AI_setHasInquisitionTarget();
	}
/************************************************************************************************/
/* RevDCM	                     END                                                            */
/************************************************************************************************/
	for (iI = 0; iI < GC.getNumCorporationInfos(); iI++)
	{
		if (pabHasCorporation[iI])
		{
			pNewCity->setHasCorporation(((CorporationTypes)iI), true, false);
		}

		if (pabHeadquarters[iI])
		{
			GC.getGameINLINE().setHeadquarters(((CorporationTypes)iI), pNewCity, false);
		}
	}

	if (bTrade)
	{
		if (isHuman() || (getTeam() == GET_PLAYER(eOldOwner).getTeam()))
		{
			pNewCity->changeHurryAngerTimer(iHurryAngerTimer);
			pNewCity->changeConscriptAngerTimer(iConscriptAngerTimer);
			pNewCity->changeDefyResolutionAngerTimer(iDefyResolutionAngerTimer);
		}

		if (!bRecapture)
		{
			pNewCity->changeOccupationTimer(iOccupationTimer);
		}
	}

	if (bConquest)
	{
		iTeamCulturePercent = pNewCity->calculateTeamCulturePercent(getTeam());

		if (iTeamCulturePercent < GC.getDefineINT("OCCUPATION_CULTURE_PERCENT_THRESHOLD"))
		{
		
/************************************************************************************************/
/* Afforess	                  Start		 07/14/10                                               */
/*                                                                                              */
/*                                                                                              */
/************************************************************************************************/
/*
			pNewCity->changeOccupationTimer(((GC.getDefineINT("BASE_OCCUPATION_TURNS") + ((pNewCity->getPopulation() * GC.getDefineINT("OCCUPATION_TURNS_POPULATION_PERCENT")) / 100)) * (100 - iTeamCulturePercent)) / 100);
*/
			int iOccupationTime = GC.getDefineINT("BASE_OCCUPATION_TURNS");\
			//ls612: Remove the old define and replace it with something that scales with Gamespeeds
			iOccupationTime += pNewCity->getPopulation() * GC.getGameSpeedInfo(GC.getGameINLINE().getGameSpeedType()).getOccupationTimePopulationPercent() / 100;
			iOccupationTime *= (100 - iTeamCulturePercent) / 100;
			
			iOccupationTime *= std::max(0,iOccupationTimeModifier);
			iOccupationTime /= 100;
			
			pNewCity->changeOccupationTimer(iOccupationTime);
/************************************************************************************************/
/* Afforess	                     END                                                            */
/************************************************************************************************/

		}

		GC.getMapINLINE().verifyUnitValidPlot();
	}
/************************************************************************************************/
/* Afforess	                  Start		 02/15/10                                               */
/*                                                                                              */
/*                                                                                              */
/************************************************************************************************/
	if (iOccupationRange > 0)
	{
		pNewCity->setOccupationCultureLevel((CultureLevelTypes)iOccupationRange);
	}
/************************************************************************************************/
/* Afforess	                     END                                                            */
/************************************************************************************************/

	pNewCity->checkBuildings(true, true, true, true, true, false);

	pCityPlot->setRevealed(GET_PLAYER(eOldOwner).getTeam(), true, false, NO_TEAM, false);

	pNewCity->updateEspionageVisibility(false);

	pCityPlot->updateCulture(true, false);

	for (iI = 0; iI < NUM_DIRECTION_TYPES; iI++)
	{
		CvPlot* pAdjacentPlot = plotDirection(pCityPlot->getX_INLINE(), pCityPlot->getY_INLINE(), ((DirectionTypes)iI));

		if (pAdjacentPlot != NULL)
		{
			pAdjacentPlot->updateCulture(true, false);
		}
	}

	//Team Project (6)
	if (hasDraftsOnCityCapture())
	{
		pNewCity->conscript(true);
	}

	bool bConquestCanRaze = false;
	if (bConquest)
	{
		PYTHON_ACCESS_LOCK_SCOPE

		CyCity* pyCity = new CyCity(pNewCity);
		CyArgsList argsList;
		argsList.add(getID());	// Player ID
		argsList.add(gDLL->getPythonIFace()->makePythonObject(pyCity));	// pass in city class
		long lResult=0;
		PYTHON_CALL_FUNCTION4(__FUNCTION__, PYGameModule, "canRazeCity", argsList.makeFunctionArgs(), &lResult);
		delete pyCity;	// python fxn must not hold on to this pointer 

		if (lResult == 1)
		{
			bConquestCanRaze = true;
		}
	}
	//	Don't bother with plot group caklculations if they are immediately to b superseded by
	//	an auto raze
	if ( bUpdatePlotGroups && (!bConquestCanRaze || !pNewCity->isAutoRaze()) )
	{
		PROFILE("CvPlayer::acquireCity.UpdatePlotGroups");

		for(int iI = 0; iI < MAX_PLAYERS; iI++)
		{
			if ( GET_PLAYER((PlayerTypes)iI).isAlive() )
			{
				if ( originalTradeNetworkConnectivity[iI] == NULL )
				{
					if ( pCityPlot->isTradeNetwork(GET_PLAYER((PlayerTypes)iI).getTeam()) )
					{
						GET_PLAYER((PlayerTypes)iI).updatePlotGroups(pCityPlot->area());
					}
				}
				else
				{
					originalTradeNetworkConnectivity[iI]->recalculatePlots();
				}
			}
		}
	}

	CvEventReporter::getInstance().cityAcquired(eOldOwner, getID(), pNewCity, bConquest, bTrade);

/************************************************************************************************/
/* BETTER_BTS_AI_MOD                      10/02/09                                jdog5000      */
/*                                                                                              */
/* AI logging                                                                                   */
/************************************************************************************************/
	if( gPlayerLogLevel >= 1 )
	{
		logBBAI("  Player %d (%S) acquires city %S bConq %d bTrade %d", getID(), getCivilizationDescription(0), pNewCity->getName(0).GetCString(), bConquest, bTrade );
	}
/************************************************************************************************/
/* BETTER_BTS_AI_MOD                       END                                                  */
/************************************************************************************************/

	SAFE_DELETE_ARRAY(pabHasReligion);
	SAFE_DELETE_ARRAY(pabHolyCity);
	SAFE_DELETE_ARRAY(pabHasCorporation);
	SAFE_DELETE_ARRAY(pabHeadquarters);
	SAFE_DELETE_ARRAY(paiNumRealBuilding);
	SAFE_DELETE_ARRAY(paiBuildingOriginalOwner);
	SAFE_DELETE_ARRAY(paiBuildingOriginalTime);

	if ( bConquestCanRaze )
	{
		//auto raze based on game rules
		if (pNewCity->isAutoRaze())
		{
			if (iCaptureGold > 0)
			{
				MEMORY_TRACK_EXEMPT();

				szBuffer = gDLL->getText("TXT_KEY_MISC_PILLAGED_CITY", iCaptureGold, pNewCity->getNameKey());
				AddDLLMessage(getID(), true, GC.getEVENT_MESSAGE_TIME(), szBuffer, "AS2D_CITYRAZE", MESSAGE_TYPE_MAJOR_EVENT, ARTFILEMGR.getInterfaceArtInfo("WORLDBUILDER_CITY_EDIT")->getPath(), (ColorTypes)GC.getInfoTypeForString("COLOR_GREEN"), pNewCity->getX_INLINE(), pNewCity->getY_INLINE(), true, true);
			}

			pNewCity->doTask(TASK_RAZE);
		}
		else if (!isHuman())
		{
			AI_conquerCity(pNewCity); // could delete the pointer...
		}
		else
		{
			//popup raze option
			eHighestCulturePlayer = pNewCity->getLiberationPlayer(true);
			bRaze = canRaze(pNewCity);
			bGift = ((eHighestCulturePlayer != NO_PLAYER) 
					&& (eHighestCulturePlayer != getID()) 
					&& ((getTeam() == GET_PLAYER(eHighestCulturePlayer).getTeam()) 
						|| GET_TEAM(getTeam()).isOpenBorders(GET_PLAYER(eHighestCulturePlayer).getTeam()) 
						|| GET_TEAM(GET_PLAYER(eHighestCulturePlayer).getTeam()).isVassal(getTeam())));

			if (bRaze || bGift)
			{
				CvPopupInfo* pInfo = new CvPopupInfo(BUTTONPOPUP_RAZECITY);
				pInfo->setData1(pNewCity->getID());
				pInfo->setData2(eHighestCulturePlayer);
				pInfo->setData3(iCaptureGold);
				gDLL->getInterfaceIFace()->addPopup(pInfo, getID());
			}
			else
			{
				pNewCity->chooseProduction();
				CvEventReporter::getInstance().cityAcquiredAndKept(getID(), pNewCity);
			}
		}
	}
/************************************************************************************************/
/* REVOLUTION_MOD                         06/27/10                                jdog5000      */
/*                                                                                              */
/*                                                                                              */
/************************************************************************************************/
/* original code
	else if (!bTrade)
*/
	// Silences double ask for accepting new city from Revolution mod
	else if (!bTrade && (GC.getGameINLINE().isOption(GAMEOPTION_NO_REVOLUTION)) )
/************************************************************************************************/
/* REVOLUTION_MOD                          END                                                  */
/************************************************************************************************/
	{
		if (isHuman())
		{
			CvPopupInfo* pInfo = new CvPopupInfo(BUTTONPOPUP_DISBANDCITY);
			pInfo->setData1(pNewCity->getID());
			gDLL->getInterfaceIFace()->addPopup(pInfo, getID());
		}
		else
		{
			CvEventReporter::getInstance().cityAcquiredAndKept(getID(), pNewCity);
		}
	}

	// Forcing events that deal with the old city not to expire just because we conquered that city
	for (CvEventMap::iterator it = m_mapEventsOccured.begin(); it != m_mapEventsOccured.end(); ++it)
	{
		EventTriggeredData &triggerData = it->second;
		if((triggerData.m_eOtherPlayer == eOldOwner) && (triggerData.m_iOtherPlayerCityId == iOldCityId))
		{
			triggerData.m_iOtherPlayerCityId = -1;
		}
	}
}
 
That's still an issue? That's important enough to address before v36 and shouldn't be too difficult to call for a local recalculation on any city just conquered. Probably already does... just out of order somewhere.

Interesting effect... wasn't aware of it. You've explained it quite well this time.

I have not played C2C for several weeks and didn't plan to until I'm finished with my Europa Universalis 4 world conquest attempt. But I'll update to the latest SVN and play a quick game tomorrow to see if the bug still exists.
 
I have not played C2C for several weeks and didn't plan to until I'm finished with my Europa Universalis 4 world conquest attempt. But I'll update to the latest SVN and play a quick game tomorrow to see if the bug still exists.

It does, at least for me. i just updated to the latest version today - unless you mean starting from scratch and seeing if the multiplicative effect still happens. If so, Godspeed, you crazy brave bastard.
 
CTD, dont know if its the Civics from Toffer or not??

Something is quite strange about this one. I can't see how it got to where it did if it was going to have the problem it had. Very odd indeed. Unit group counts have been reported as being flawed before... Might have something to do with that.

Is this a repeatable CTD? If not, it might be a bad memory segment or something.

No 'solution' stands out as obvious because it looks like it shouldn't have gotten that far to begin with. If it's repeatable I could evaluate it more closely and have a bit more faith in the accuracy of some of the variable values being reported.
 
That's still an issue? That's important enough to address before v36 and shouldn't be too difficult to call for a local recalculation on any city just conquered. Probably already does... just out of order somewhere.

Interesting effect... wasn't aware of it. You've explained it quite well this time.

EDIT: Wow... it's complicated I'll give you that. Entirely possible something is skewed. It will take a fairly major auditing process to make sure its resolved properly.

Yep the bug still exists. I have downloaded the latest SVN, conquered a city with a spiked clubman rush, and the production of my new city is all screwed up.

Hammers: I count 5 from tiles, 2 from buildings, 2 from wonder, 3 from special buildings which should give 12 hammers production. However, the base hammer production from the city is stated as 16. Which probably corresponds with the 2 from buildings and the 2 from wonders being counted double.

Food: I count 6 from tiles, 8 from buildings and 2 from wonders which should give 16 food. However the base food production is stated as 27. The mouse popup on base total food production says 6 from tiles, 9 from buildings for a total of 27!? No mention of the food production by wonders. I guess 1 food building got destroyed, and 11 ghost food gets produced from ghost buildings (9) and ghost wonder (2).

In other words, the production calculation of conquered cities is still screwed up.

Anyway I have posted several bug reports, screenshots and saves in this thread before so I refer to those.

However, recalculate (shift-ctrl-T) sets base hammers to 12 (was 16) and food to 16 (was 27), as they should be.
 
Yep the bug still exists. I have downloaded the latest SVN, conquered a city with a spiked clubman rush, and the production of my new city is all screwed up.

Hammers: I count 5 from tiles, 2 from buildings, 2 from wonder, 3 from special buildings which should give 12 hammers production. However, the base hammer production from the city is stated as 16. Which probably corresponds with the 2 from buildings and the 2 from wonders being counted double.

Food: I count 6 from tiles, 8 from buildings and 2 from wonders which should give 16 food. However the base food production is stated as 27. The mouse popup on base total food production says 6 from tiles, 9 from buildings for a total of 27!? No mention of the food production by wonders. I guess 1 food building got destroyed, and 11 ghost food gets produced from ghost buildings (9) and ghost wonder (2).

In other words, the production calculation of conquered cities is still screwed up.

Anyway I have posted several bug reports, screenshots and saves in this thread before so I refer to those.

However, recalculate (shift-ctrl-T) sets base hammers to 12 (was 16) and food to 16 (was 27), as they should be.
Ok, important to fix but very complex as you can see from the posted code above. I need to figure out where either a double summing is taking place or values haven't been removed that should've been before resetting them.
 
Rev: later than 8653

I get this python error when hovering over one of the options in the Supervirus outbreak popup.

Code:
Traceback (most recent call last):

  File "CvRandomEventInterface", line 7798, in getHelpSuperVirus3

AttributeError: 'CvTechInfo' object has no attribute 'getTextKeyWide'
ERR: Python function getHelpSuperVirus3 failed, module CvRandomEventInterface

Another one when building the Hypersonic Recon Plane:

Code:
Traceback (most recent call last):
  File "BugEventManager", line 363, in _handleDefaultEvent
  File "UnitNameEventManager", line 245, in onUnitBuilt
  File "UnitNameEventManager", line 449, in getUnitNameConvFromIniFile
  File "BugCore", line 147, in get
  File "BugCore", line 118, in _getOption
ConfigError: Option UnitNaming__Combat_AIR_RECON not found in mod UnitNaming
 
Back
Top Bottom