Bug Thread

This is the "black hole too close to the edge of the map" bug. It will be fixed in the next version.

In your game there is a black hole near the upper edge of the map not too far from the center of that edge. It is 4 spaces from the edge. Sadly, that is 1 space too close. Having a ship enter a grav field that is 2 spaces from the edge of a map causes the search for the associated black hole to try to look at plots that are off the map and therefore do not actually exist, causing it to crash. If you delete that black hole in Worldbuilder, you can continue to play the save.

The issue only happens for maps that don't wrap, and only if it randomly puts a black hole too close to the edge. It doesn't happen most of the time. It doesn't happen at all if you use maps that wrap (the only one that does is the regular Final Frontier map).

Hi God-Emperor, i've been looking through the threads here and i can see the fix you've suggested to resolve the black hole issue when in-game, but is there a fix for stopping the problem from even occurring in the first place? I know you've stated it will be fixed in the next version but after all the problems i've had merging B5 with FFP i would rather just have the fix for the black hole than have to go through the merge process again.
 
Hi God-Emperor, i've been looking through the threads here and i can see the fix you've suggested to resolve the black hole issue when in-game, but is there a fix for stopping the problem from even occurring in the first place? I know you've stated it will be fixed in the next version but after all the problems i've had merging B5 with FFP i would rather just have the fix for the black hole than have to go through the merge process again.

I just checked and no code with the fix was posted, just the explanation of where it is.

From TC01's post, #98:
It's an access violation exception in CvPlot::getFeatureType(). That means that the plot instance getFeatureType() is being called on doesn't exist.

The call is coming from DoGravityField- the code Kiwikaz added for feature effects. Specifically, it occurs when checking the plots around a gravity field for the presence of a black hole.

I've fixed it by adding some checks to make sure the plot is not null before trying to get the feature type.

My guess is that a black hole is close enough to the edge of a map that some of the plots the loop is running through are invalid.

So, basically, in DoGravityField you need to make sure the plot exists before you try to call its .getFeatureType() method.
 
I have an updated location finder for the "other" type base, v a new perhaps not quite accurately named (based on actual functionality rather than desired functionality) findBestChokepoint function.

This is better than the original, but it is still not exactly what I'd call "good".

Code:
	def findBestChokepoint(self, iPlayer=-1, bCheckForVisibility=false):
		"""Returns a tuple of the best chokepoint plot and its plot value."""
		pBestPlot = -1
		iBestValue = -1
		pPlayer = -1
		iTeam = -1
		if (iPlayer >= 0):
			pPlayer = gc.getPlayer(iPlayer)
			iTeam = pPlayer.getTeam()

		iFeatNebula = gc.getInfoTypeForString('FEATURE_ICE')
		iFeatAsteroid = gc.getInfoTypeForString('FEATURE_FOREST')
			
		iMaxRange = max(CyMap().getGridWidth() / 2, 60)
		printd("findBestChokepoint    iMaxRange = %d" % (iMaxRange))		
		for iPlotLoop in range(CyMap().numPlots()):
			pLoopPlot = CyMap().plotByIndex(iPlotLoop)
			
			# If we're supposed to be checking for a player's visibility then only check this plot if it's revealed
			if (bCheckForVisibility):
				if (not pLoopPlot.isRevealed(iTeam, false)):
					continue

			# CP - Check the plot being rated to see if it already belongs to someone else.
			iPlotOwner = pLoopPlot.getOwner()
			if ((iPlotOwner != -1) and (iPlotOwner != iPlayer)):
				continue

			# Don't build anywhere except in empty space & asteroids
			if (pLoopPlot.getFeatureType() != -1 and pLoopPlot.getFeatureType() != iFeatAsteroid):
				continue

			iDistanceFromCapital = CyMap().getGridWidth()
			
			if (pPlayer.getCapitalCity()):
				iDistanceFromCapital = CyMap().calculatePathDistance(pPlayer.getCapitalCity().plot(), pLoopPlot)
			
			# Don't look too far away (performance, more than anything)
			if (iDistanceFromCapital > 0 and iDistanceFromCapital < iMaxRange):
				
				if iDistanceFromCapital < 4 : # Discourage it from building sensor stations right next to the capital
					iDistanceValueMod = -9    # it will also get a penalty down below for being close to a star system if it is within 2
				else : # Highest distance scores in the zone from 1/6 iMaxRange to 2/3 iMaxRange, in this zone iDistanceValueMod will be iMaxRange/6
					iDistanceValueMod =  ((2 * min( iDistanceFromCapital, iMaxRange/6)) - max( iDistanceFromCapital - (2 * iMaxRange / 3), 0)) / 2
				
				iPlotValue = 0
				iNumNebula = 0
				iNumAdjacentNebula = 0
				iNumAsteroid = 0
				iNumDamaging = 0
				for iXSearchLoop in range(pLoopPlot.getX()-2, pLoopPlot.getX()+3):
					for iYSearchLoop in range(pLoopPlot.getY()-2, pLoopPlot.getY()+3):
						# If the map does not wrap and the plot is not on the map give a small penalty and skip to the next.
						# Note that if the plot is off the map then all plots in that row and/or column are off too
						# so it will actually be at least 5 plots that give this penalty.
						if not CyMap().isPlot(iXSearchLoop, iYSearchLoop):
							iPlotValue -= 3
							continue
							
						pSearchPlot = CyMap().plot(iXSearchLoop, iYSearchLoop)
						
						# Don't search unseen plots in range of the one we're looking at either
						if (bCheckForVisibility):
							if (not pSearchPlot.isRevealed(iTeam, false)):
								continue

						#Build sensor stations near chokepoints -- TC01
						iFeature = pSearchPlot.getFeatureType()
						if iFeature == iFeatNebula:
							iNumNebula += 1
							if (abs(iXSearchLoop - pLoopPlot.getX()) <= 1) and (abs(iYSearchLoop - pLoopPlot.getY()) <=1):
								iNumAdjacentNebula += 1
						elif iFeature == iFeatAsteroid:
							iNumAsteroid +=1
						elif (iFeature != -1) and (gc.getFeatureInfo(iFeature).getTurnDamage() > 0): # bug fix - make sure there is a feature before trying to get the info for it, taking advantage of the short-circuit conditional evaluation
							iNumDamaging += 1
						elif iFeature == gc.getInfoTypeForString('FEATURE_SOLAR_SYSTEM'):
							iPlotValue -= 22 # reduce value a lot if near a star system
						
						#If other stations are present, no build -- TC01
						for iUnit in range(pSearchPlot.getNumUnits()):
							pOtherStarbase = pSearchPlot.getUnit(iUnit)
							if pOtherStarbase.isStarbase():
								# iPlotValue = 0
								iPlotValue -= 99
								break

				# Some nebula is a good indication of a choke point.
				# Too much is an indication that we are in a box canyon.
				# If there are 7 or more adjacent nebula plots, then this is a bad location. Otherwise:
				# As a guess, make it increase the value for more up to a max value at 13, then decrease fairly rapidly.
				# Give a score of 0 for 0, increaseing by 3 per nebula up to a score of 39 at 13 through 15,
				# then decreasing by 5 per nebula over 15.
				# This is -1 at 23, -6 at 24 and -11 at 25 (which is not a valid location anyway; neither is one
				# with 23 or 24 since it is unreachable from the capital so the iDistanceFromCapital condition
				# rules it out before we get here).
				# Additionally, if there are more than 4 (i.e. 5 or 6) immediately adjacent nebula plots, give a
				# small penalty of -2.
				if iNumAdjacentNebula > 6 :
					iPlotValue -= 99
				else:
					iPlotValue += ( 3 * min( iNumNebula, 13)) - ( 5 * max( iNumNebula - 15, 0))
					if iNumAdjacentNebula > 4 :
						iPlotValue -= 2 

				# A few asteroids are OK, but they block the visibility (and visibility is the whole point of a sensor station)
				# With 0 no change, then +5 for 1-3 (which is the max bonus), then -1 for each over 3.
				# Note that there is still a bonus for being on top of asteroids given later.
				iPlotValue += ( 5 * min( iNumAsteroid, 1)) - max( iNumAsteroid - 3, 0)
				
				# Damaging features are good, but too many is not as good since the area will tend to be avoided and
				# it is probably between two black holes/supernovas (which is a good chokepoint, but bad for the visibility
				# aspect since looking at a lot of such plots is rather pointless).
				# Give +2 per, up to a max of +30 at 15, then -1 per damaging feature over 15
				iPlotValue += ( 2 * min( iNumDamaging, 15)) - max( iNumDamaging - 15, 0)
				
				iPlotValue += iDistanceValueMod

				# Little extra bonus for being in Asteroids (defense)
				if (pLoopPlot.getFeatureType() == iFeatAsteroid):
					iPlotValue += 4		#How small should it be?

				# If this plot has the most resources in range from what we've found
				if (iPlotValue > iBestValue):
					iBestValue = iPlotValue
					pBestPlot = pLoopPlot
				
				printd("plot %d (%d,%d) value = %d (distance=%d (for %d), NumNebula=%d (adjacent=%d), NumAsteroid=%d, NumDamaging=%d)" % 
						(CyMap().plotNum(pLoopPlot.getX(), pLoopPlot.getY()), pLoopPlot.getX(), pLoopPlot.getY(), 
						iPlotValue, iDistanceFromCapital, iDistanceValueMod, iNumNebula, iNumAdjacentNebula, iNumAsteroid, iNumDamaging))
					
		printd("* best plot = %d (%d,%d), value = %d" % (CyMap().plotNum(pBestPlot.getX(), pBestPlot.getY()), pBestPlot.getX(), pBestPlot.getY(), iBestValue))
			
		return [pBestPlot, iBestValue]

This function seems to max out at a rating of 52 on the map in the Galaxy scenario.

I suggest changing the threshold in the canConstructSensorStation from 10 up to 45, on the "if (iBestValue > 10)" line.

I think it might also be a good idea to have the threshold adjusted so that it increases by 1 per sensor station that has already been built. If this is not done, the AIs could ruin their economies on a large map like the Galaxy map by building lots of sensor stations (which are then wiped out by hostile enemies and others since they are strength 0 and the AI doesn't appear to send any ships to protect them).

The floating threshold version of canConstructSensorStation looks like this:
Code:
	def canConstructSensorStation(self, pUnit, iBuild):
		"""This function checks if the AI can build a sensor station - it uses specific sensor station checks"""
		bValid = false
		pBestPlot, iBestValue = self.findBestChokepoint(pUnit.getOwner(), true) # bug fix - was trying to use non-existent iPlayer
		if (pBestPlot != -1):
			iX = pBestPlot.getX()
			iY = pBestPlot.getY()

			pBuildInfo = gc.getBuildInfo(iBuild)
			pImprovementInfo = gc.getImprovementInfo(pBuildInfo.getImprovement())
			pCivilization = gc.getCivilizationInfo(pUnit.getCivilizationType())
			iBuildUnit = pCivilization.getCivilizationUnits(pImprovementInfo.getUnitClassBuilt())
			pyPlayer = PyPlayer(pUnit.getOwner())
			apUnitList = pyPlayer.getUnitsOfType(iBuildUnit)
			iThreshold = 45 + len(apUnitList)
			printd("canConstructSensorStation: threshold=%d, best=%d" % (iThreshold, iBestValue))
			if (iBestValue > iThreshold):	# was 10 with old system		#What should be the cutoff for a really good value?
				bValid = True
			else:
				iX = -1
				iY = -1
		return (bValid, iX, iY)
I have figures out why it is building two things at one place.

The thing is that it thinks it is building only outposts. The reason for this is that the ImprovementInfo stores the unit class to make, but the code is taking that number and using it as the unit type. This makes its checks use a semi-random unit. The check does a "if (pUnitInfo.isStarbase() and not pUnitInfo.isOtherStation()):" on this semi-random pUnit, which (not surprisingly) fails. It then falls through to the "else" part which calls canConstructSensorStation. It is never using canConstructStarbase.

To fix this, I made it get the unit type for the unit class that is appropriate for the civ in question (so it should work even for a starbase UU). The start of the doStationConstructionAI function now looks like this:

Code:
Code:
def doStationConstructionAI(self, pUnit, iBuild):
		"""This function decides what set of other functions to run depending on what the station type is."""
		pBuildInfo = gc.getBuildInfo(iBuild) # bug fix - was using the non-existent "iStation" instead of iBuild
		pImprovementInfo = gc.getImprovementInfo(pBuildInfo.getImprovement())
		pCivilization = gc.getCivilizationInfo(pUnit.getCivilizationType()) # bug fix - part of the fix for the next line
		pUnitInfo = gc.getUnitInfo(pCivilization.getCivilizationUnits(pImprovementInfo.getUnitClassBuilt())) # bug fix -  was doing the getUnitInfo on the unit class directly
		pPlayer = gc.getPlayer(pUnit.getOwner())
		pTeam = gc.getTeam(pPlayer.getTeam())
Ran the same turn from the same save as before and now everybody is sending construction ships to two different places. The sensor station locations are still the dead-end-hole-in-a-nebula type places, but the designated starbase builders are headed towards the more usual, and useful, types of places.

I will be posting some improved choke-point locater code soon. It still won't be great, but it will be better.
Hi God-Emperor i've read through the info in both these posts but have no idea which file i need to go into to make the required changes. Is it a Python file or is it a C++ file?
 
That's peculiar, i had some C++ exceptions (no CtD's) when playtesting the B5 mod the other day, didn't take screen shots like i should have done and i assumed it was down to this problem. I'll have to go back and see if i can repeat the error and get a screen shot.
 
I posted those two things in the wrong thread. They were supposed to be over in the Modder's Guide thread, along with the other posts about the same issue.

As mentioned by Deanej, they are not general fixes that need to be applied to the game. They are only valid for the optional (and previously untested) version of the starbase AI that tries to build both starbases and sensor stations (the standard FFP Python AI stuff never builds sensor stations). I think that is part of the "Mod Platform Plugins" download. I only tested the changes I posted in the Star Trek Galaxy scenario, with a rather limited amount of testing.

At some point this will probably be added to the base FF+, but I think it needs more testing. As it is, the positioning of the sensor stations in findBestChokepoint is, shall we say, "iffy". The AI also does not seem to guard the sensor stations, so you have strength 0 ships sitting out all alone and ready to be wiped out by the first pirate that comes by (which is why I think they should be given some strength, as mentioned in some thread a while back).
 
Does the partisans event work? Someone's been getting a CTD with it in Star Trek (heavily modded), but I think the issue stems back to Final Frontier since I had issues with events giving units in the past.
Thanks deaneJ i now know what i'm looking for, i need to make sure the event is geared to give B5 orientated units, assuming it works correctly.
 
Actually this wasn't in response to your post.
Oh well, not to worry, it has still helped me lol
Partisans reads what unit it needs from the conscription system, so if drafting works, you don't have to do anything with partisans.
I need to check what units i have set to conscription.
 
Does the partisans event work? Someone's been getting a CTD with it in Star Trek (heavily modded), but I think the issue stems back to Final Frontier since I had issues with events giving units in the past.

I just posted about this over in the ST thread.

I'll try and post a fixed CvRandomEventInterface.py later today.
 
Here is a new CvRandomEventInterface.py that should fix the partisans event issues.

Well, assuming that the only problem is attempting to create units of the type that can currently be drafted in the capital when there is no such unit type. In looking over the code I saw no other obvious issue.

I tested it but only when there were conscriptable units (I razed a large well developed star system and the message indicated that the AI created partisans in its capital), so the code itself works without syntax errors. I'm not sure what happens if there are no such units since it rules out both possible event choices. I think an event trigger just doesn't do anything if none of its events are possible since presenting a pop-up with no actual valid choices to click on would be bad.
 

Attachments

Hi guys, I can't get an extraction facility to complete properly in my current game. I'm using 1.651 patch, game speed is epic. I'm using the steam version, don't know if that makes a difference or not.
 
Are you sure you are using 1.651 and not 1.61, or just 1.6?

A bug like that was fixed in 1.62, so a bug like that was in 1.61 and 1.6 might have had it too (I don't remember).

Try applying the 1.651 patch again.
 
where do I install 1.651 patch? I had trouble installing the main file, but after the 3rd attempt I finally got it right. I think that earlier I installed it in the main FFP folder, I'll try it again now.

aha, thanks! must have incorrectly installed 1.651 before, I reloaded the save game and it was working.

btw, those crazy killer barbarians were a real PITA!!
 
FF has always had an issue with lost production when you change the current build planet while something in the build queue has some production already spent on it.

There is actually a mechanism to deal with this, the problem is that it only works on the first thing in the queue. That one item is checked to see if the new build planet has ever spent any production on it, any building that is not the first thing in the queue is never checked.

I have fixed this. (Mostly - there are still some issues, some of which I may get to later.)

Here is my note in my change log, which includes a lot of info about the problem:
Spoiler :
Code:
Remember production spent on buildings when changing the current build planet.
	Code to do this was already in there, but it rarely worked as
	expected - it only worked if you switched back and forth but
	did not change the build queue.
	
	Fixed so that it works more like one might expect.
	This involved changing how a mod net message was handled, the
	self.iNetMessage_AssignBuilding variety. The primary change is that
	it now sets the CvCity's entire list of production spent on every
	building type to those stored for the new build planet, not just
	for the type of the first entry in the build queue. It also now
	always does this, whether or not the current build queue entry is
	a building, so everythign in the queue is adjusted (i.e. if the
	3rd thing in the build queue is a building that already had 33
	production spent on it on this planet, it will now get those 33;
	it used to only update data for the first thing in the queue).
	
	Remaining issues: production decay and captured star systems.
	Ordinarily when you insert things in the build queue in front
	of somethign that already has production spent on it, after a
	while (10 turns or so, this may be game speed dependent) it
	starts to lose the stored production, 1 per turn. THis does
	not happen to production saved up when switching planets -
	but I don't think this is a bad thing.
	Also, a player will inherit the all stored up production for
	planets in star systems that are captured. This may only
	happen when recapturing a system that was taken from you
	or in multiplayer games since I don't think the AI ever
	uses the mod net message to change planets and so it never
	stores up any production. If the AI somehow changes the build
	planet in the middle of a build it will always lose any
	production it has spent on the building - this is probably
	actually happening since it can actually reevaluate its
	build at various times, like when it gains a tech, and when
	doing so the cannotConstruct routine can cause the current
	build planet to change. Perhaps I should change the AI to update
	this data everywhere it can change the current build planet...
	(That would be in CvGameUtils.py, or the BUGified equivalent,
	and CvAI.py.) There is also at least two places the build
	planet change can happen without checking this for a human player
	controlled system - in the onNukeExplosion code and in the
	onCityAcquired code.
	
	Modifed file:
		Python\CvFinalFrontierEvents.py

Rather than include the modified file, I'll just include the two changed sections of code here, since I'm currently working with 2 different versions - the regular FFP and the Beta merge with BUG - and I may do some additional work to store the spent production for the AI when it may be switching build planets at somewhat random times. If I do those fixes too, I'll provide a set of files.

In the CvFinalFrontierEvents.py (and/or FinalFrontierEvents.py for the BUG merge version) there are two places with changes.

In the onModNetMessage function remove everything inside this elif block
Code:
elif (iMessage == self.iNetMessage_AssignBuilding):
(it should be everything after that line to the end of the function)
Note that this is preceded by an incorrect comment, "# Remove a certain amount of population from a planet" - this is a case of too much cut and paste since the comment matches the one for the previous elif (where it is correct). That could also be fixed, I suppose.

and replace it with this:
Code:
		elif (iMessage == self.iNetMessage_AssignBuilding):
		
			#CyMessageControl().sendModNetMessage(FinalFrontier.iNetMessage_AssignBuilding, pSystem.getX(), pSystem.getY(), iPlanetRing, -1)
			
			iX = iData2
			iY = iData3
			iPlanetRing = iData4
			iRemove = iData5
			
			pPlot = CyMap().plot(iX, iY)
			pCity = -1
			if (pPlot.isCity()):
				pCity = pPlot.getPlotCity()
				
			pSystem = self.getSystemAt(iX, iY)
			pPlanet = pSystem.getPlanet(iPlanetRing)
			
			pOldPlanet = pSystem.getPlanet(pSystem.getBuildingPlanetRing())
			
			# Planet Production Memory Improvement - GE, March-2011
			# If we switched build planet and the first entry in the current build
			# queue was a building that already existed on the planet it removed that
			# entry from the queue but did not check the next entry to see if that
			# building also already existed. Now loop back and check again if we
			# remove something from the queue. Presumably this issue is dealt with
			# in the DLL at some point, but as long as it was being done here it
			# may as well keep checking.
			#
			# The main fix is that we don't just set the stored production for
			# the building type of the first queue entry. The CvCity object stores
			# how much production the city has already spent on each building type
			# (which is why you can add an item to the front of the queue and not
			# have the thing you were working on get reset to 0 production spent
			# on it. But we have a separate list for each planet, so now it loads
			# the entire list here - every building type gets it's stored production
			# value updated from the new build planet's list. This is always done,
			# regardless of what type of thing is currently being produced.
			# There is still probably an issue with production decay (normally,
			# if you don't work on something for a while the saved production
			# starts going down - it is something like -1 hammer per turn if you
			# don't work on it for 10 turns, but this may depend on game speed).
			#
			# There is another piece of code down in the onBuildingBuilt to
			# zero out the stored production for a building that is finished.
			#
			# Currently there may also be an issue in star systems that are
			# captured - they currently retain all the stored production
			# data. This doesn't seem like a bad thing in general, however
			# if a building that is normally wiped out when a city is captured
			# has production stored up, that building will be easier to produce
			# than normal on the planet with the production stored for it.
			# At some point, the onCityACquired function could be modified to
			# deal with this - as a minimum any building type marked as Never
			# Capture or with a survival probablity of 0 should probably have
			# it's stored production set to 0.

			# Working on a building?
			if (pCity.isProductionBuilding()):
			
				iBuilding = pCity.getProductionBuilding()
			
				pOldPlanet.setBuildingProduction(iBuilding, pCity.getProduction())
			
				szText = "Old Planet: %s (ring=%d,type=%s)" %(pOldPlanet.getName(), pOldPlanet.getOrbitRing(), aszPlanetTypeNames[pOldPlanet.getPlanetType()])
				printd(szText)
				printd("  production saved for old planet: save %d for production of building %d" %(pCity.getProduction(), iBuilding))
				printd("New Planet: %s" % (pPlanet.getName()))
				bLoop = True
				while bLoop:
					bLoop = False
					if (pPlanet.isHasBuilding(iBuilding)):
						# Planet already has this building, pop the queue
						pCity.popOrder(0, false, true)
						printd("  new planet already has building %d, removing from build queue" %(iBuilding))
						# Check if new production is a building we already have too
						if (pCity.isProductionBuilding()):
							bLoop = True
							iBuilding = pCity.getProductionBuilding()
			
			# Load the new build planet's data for saved production amounts into the city object for all building types
			printd("  Adjusting stored production values for the city based on new planet's settings")
			for iBuilding in range(gc.getNumBuildingInfos()):
				pCity.setBuildingProduction(iBuilding, pPlanet.getBuildingProduction(iBuilding))
				printd("    building type %d set to %d" %(iBuilding, pPlanet.getBuildingProduction(iBuilding)))
			
			CyInterface().setDirty(InterfaceDirtyBits.CityScreen_DIRTY_BIT, True)
			
			pSystem.setBuildingPlanetRing(iPlanetRing)
			
			CyInterface().setDirty(InterfaceDirtyBits.CitizenButtons_DIRTY_BIT, True)
			CyInterface().setDirty(InterfaceDirtyBits.SelectionButtons_DIRTY_BIT, True)
(I know it probably includes way too many comment lines.)

Also, in onBuildingBuilt add this to the end of the function:
Code:
		# Planet Production Memory Improvement - GE, March-2011
		# This is part 2 of the fix, the first part is in the onModNetMessage function.
		# Here we just zero out the saved production for the building type we just built.
		pPlanet.setBuildingProduction(iBuildingType, 0)
		printd("Zeroed production for building %d on planet %s" %(iBuildingType, pPlanet.getName()))


You can comment out all the printd() calls if you want - they add even more stuff to the already huge amount of stuff being printed to the Python debug log if this is activated at the top of CvSolarSystem.py.
 
As long as I was posing so much info about it, I'll point out that there is another issue for saving partial production that the above fix doesn't fix...

When you switch build planets, only the first thing in the queue is checked. If it is a building then its current production is saved for the planet before the build planet is switched.

If you spend some production on a building and then inserted something else, building or otherwise, into the start of the queue in front of it and then switch the build planet you will lose the production. It is still saving only the production for the first thing in the queue (if it is a building). Another of the things I may do is figure out how to check everything in the entire build queue and save the info for all the buildings in it, not just for the first thing in the queue.
 
OK, I have produced a better fix for the production memory problem than the one a couple posts back.

This one should solve all of the problem other than production decay and captured star systems remembering the previous owner's stored up production values.

This is the contents of the included change file:
Spoiler :
Code:
Planet Production Memory Improvement:
Remember production spent on buildings when changing the current build planet.
	Code to do this was already in there, but it rarely worked as
	expected - it only worked if you switched back and forth but
	did not change the build queue.
	
	Fixed so that it works more like one might expect.
	This involved changing how a mod net message was handled, the
	self.iNetMessage_AssignBuilding variety. The code for adjusting
	the saved production data has been removed from here. All the
	adjusting is now done in the CvSolarSystem.py in
	the CvSystem.setBuildingPlanetRing function. Doing it there
	simultaneously solves the problem for the AI's build planet
	changes as well as for the human player.
	
	The primary Fix is that CvSystem.setBuildingPlanetRing
	now does 2 thigns:
	It stores the CvCity object's saved production values for every
	building type into the pre-change build planet's list of building
	production values and it sets the CvCity's entire list of production
	spent on each building type to those stored by the new build planet.
	It also now always does this, formerly adjustments were made only if
	the current build queue entry was a building, and only for the first
	thign in the queue.
	
	Remaining issues: production decay and captured star systems.
	Ordinarily when you insert things in the build queue in front
	of somethign that already has production spent on it, after a
	while (10 turns or so, this may be game speed dependent) it
	starts to lose the stored production, 1 per turn. Ths does
	not happen to production saved up when switching planets -
	but I don't think this is a bad thing.
	Also, a player will inherit the all stored up production for
	planets in star systems that are captured.
	
	Modifed file:
		Python\CvFinalFrontierEvents.py
		Python\CvSolarSystem.py

The changes are marked with "# Planet Production Memory Improvement - GE, March-2011", with changes in 3 places. In CvFinalFrontierEvents.py there are changes to the handling of the iNetMessage_AssignBuilding in the onModNetMessage function, and an addition to the end of the onBuildingBuilt fucntion. In CvSolarSystem.py the CvSystem.setBuildingPlanetRing function has a lot of new code.

Attached is a zip file with the changes text file and the two affected Python files.
Well, it would be but uploading attachments still doesn't work...

This is for regular FFP, not the BUG beta (which has the same issue and would
need the same fix, although the changes to both files would need to be duplicated, those in CvFinalFrontierEvents.py in FinalFrontierEvents.py instead and you can't just swap the CvSolarSystem.py files since FFPBUG's version of this file has a bunch of changes that are not in this one so they would also need a merge operation.).
 
Thanks God-Emperor; when attachment posting is sorted out, I'll merge this in.

And then I'll probably release 1.7, as FFPBUG should be merged by then.
 
Back
Top Bottom