Final Frontier Plus BUG

The problem with the PLE code that I thought I had fixed back in post 17 happened to me again. Evidently it can still try to show info for dead construction ships after they build a starbase when there is another unit on the same plot.

So another attempt at fixing...

On line 290 I added another check. Hopefully, this will catch everything so no more bad units will slip through.

Code:
				if (pLoopUnit and not pLoopUnit.isNone() and not pLoopUnit.isDead()): # G-E bugfix - don't show dead units

I still can't be certain this fixes it. When is a unit not a valid unit anymore?

Hopefully the new .isNone() check will catch whatever slipped though without it, or at least some of it. On the other hand, it really should have failed the .isDead() check if it was None with the typical error that would look like "'NoneType' object has no attribute 'isDead'". Because of that, I suspect that this will not really fix it. I'm beginning to think that maybe there is some issue with the unit being half-dead, in effect: some of its data is gone (set to None or various C++ equivalents like setting pointers to NULL) but the unit is not yet marked as dead. It therefore passes the validation but doing a variety of things with it causes some to fail (the current crop of errors had it failing when calling .isSelected() and also when trying to get its button image via gc.getUnitInfo(pLoopUnit.getUnitType()).getButton(), which indicated that the unit info was None).

In essence, it seems to be acting like the function that kills the unit is clearing out its data before marking it as dead when what it should be doing is marking the unit dead as the very first thing, then begin the cleanup.

If anybody has any suggestions for more checks that can be done to validate the unit to avoid all these errors, I'd like to hear them.

I'm considering adding more validation (a check that matches the one above) near the beginning of the displayUnitPlotListObjects function, which is where it keeps failing in various ways. Perhaps this later validation would catch it. Unfortunately, it doesn't seem likely due to the lack of multithreading in Civ (if it is semi-dead before the function call, it should still be in the same state after the function call and therefore it should still not fail an identical set of validations since a single threaded application should not be able to do two things, run Python code and continue to modify the object in the DLL, at the same time). On the other hand, it does act like the object is slowly changing since the exact error changes. Initially it failed a few time on the .isSelected() call (11 times). It then switched to failing when trying to get the button (391 times), which happens earlier in the function. It's not clear what ended the mass of errors. It probably either ended because the DLL finished deleting the object, or finally marked it as being dead, or it may have stopped generating errors because I minimized the game (from full screen) and then brought it back, or from when I then clicked on another plot with units on it - it took quite a few clicks to get through the pile of error messages after that but it could have stopped generating more at either of those times.

I guess that's enough grumbling about this (for now).
 
So, I finally had the time to merge it.

Encountering a problem however. Something is wrong with FFMapscriptCore and/or the mapscripts themselves and/or... uh, anything else. Cities are not being generated on solar system plots. This behavior does not occur in FFPBUG or FF+ 1.7 pre-BUG, so I'm not sure what's causing it right now. I intend to look into it more tomorrow.

But I just thought I'd post a status update. I know I haven't done much Civ 4 modding lately; I apologize for that. Hopefully I'll be doing more again in the future; and in any case I intend to make a SVN/GIT/Google Code/whatever repository for the mod to make the release process less dependent on me.

EDIT: This is definitely an FFMapscriptCore problem; or possibly a problem with how FFMapscriptCore integrates with the mapscripts.

What I can't understand is why it doesn't occur without BUG (my pre-BUG working copy of FF+ 1.7 works fine). However, the mapscripts with FFPBUG (that don't use FFMapscriptCore) work fine.

If I can't figure this out, I'll just release 1.7 without FFMapscriptCore for now. But as I really like the idea of one module acting as a library for the mapscripts, I'll definitely work on it more.

EDIT 4: See the next post for debugging information and some relevant code.
 
I've "fixed" this by adding a check to verify that the plot has FEATURE_SOLAR_SYSTEM after placing the city and starting units.

A check for this before all that (when scanning random plots) does not seem to have any affect.

Here is the debugging information for a sample run through of FinalFrontier Tiny with three players, if anyone wants to try to figure this out.

Spoiler :
Code:
Checking for player 0 in

[]

Solar System Plot List is of size 0

Randomly chosen plot is at 16, 22

Validity = 0

Player ID = 0, Pass = 0, Failed!

Randomly chosen plot is at 46, 4

Validity = 0

Player ID = 0, Pass = 1, Failed!

Randomly chosen plot is at 49, 18

Validity = 0

Player ID = 0, Pass = 2, Failed!

Randomly chosen plot is at 23, 20

Validity = 0

Player ID = 0, Pass = 3, Failed!

Randomly chosen plot is at 9, 18

Validity = 0

Player ID = 0, Pass = 4, Failed!

Randomly chosen plot is at 38, 17

Validity = 0

Player ID = 0, Pass = 5, Failed!

Randomly chosen plot is at 2, 24

Validity = 0

Player ID = 0, Pass = 6, Failed!

Randomly chosen plot is at 36, 26

Validity = 0

Player ID = 0, Pass = 7, Failed!

Randomly chosen plot is at 46, 4

Validity = 0

Player ID = 0, Pass = 8, Failed!

Randomly chosen plot is at 6, 5

Validity = 0

Player ID = 0, Pass = 9, Failed!

Randomly chosen plot is at 38, 17

Validity = 0

Player ID = 0, Pass = 10, Failed!

Randomly chosen plot is at 9, 27

Validity = 0

Player ID = 0, Pass = 11, Failed!

Randomly chosen plot is at 6, 5

Validity = 0

Player ID = 0, Pass = 12, Failed!

Randomly chosen plot is at 23, 20

Validity = 0

Player ID = 0, Pass = 13, Failed!

Randomly chosen plot is at 21, 6

Validity = 0

Player ID = 0, Pass = 14, Failed!

Randomly chosen plot is at 36, 26

Validity = 0

Player ID = 0, Pass = 15, Failed!

Randomly chosen plot is at 39, 10

Validity = 0

Player ID = 0, Pass = 16, Failed!

Randomly chosen plot is at 49, 18

Validity = 0

Player ID = 0, Pass = 17, Failed!

Randomly chosen plot is at 6, 5

Validity = 0

Player ID = 0, Pass = 18, Failed!

Randomly chosen plot is at 2, 24

Validity = 0

Player ID = 0, Pass = 19, Failed!

Randomly chosen plot is at 36, 26

Validity = 0

Player ID = 0, Pass = 20, Failed!

Randomly chosen plot is at 39, 10

Validity = 0

Player ID = 0, Pass = 21, Failed!

Randomly chosen plot is at 16, 22

Validity = 0

Player ID = 0, Pass = 22, Failed!

Randomly chosen plot is at 9, 18

Validity = 0

Player ID = 0, Pass = 23, Failed!

Randomly chosen plot is at 6, 5

Validity = 0

Player ID = 0, Pass = 24, Failed!

Randomly chosen plot is at 46, 11

Validity = 0

Player ID = 0, Pass = 25, Failed!

Randomly chosen plot is at 23, 20

Validity = 0

Player ID = 0, Pass = 26, Failed!

Randomly chosen plot is at 9, 18

Validity = 0

Player ID = 0, Pass = 27, Failed!

Randomly chosen plot is at 39, 10

Validity = 0

Player ID = 0, Pass = 28, Failed!

Randomly chosen plot is at 38, 17

Validity = 0

Player ID = 0, Pass = 29, Failed!

Randomly chosen plot is at 38, 17

Validity = 0

Player ID = 0, Pass = 30, Failed!

Randomly chosen plot is at 17, 15

Validity = 0

Player ID = 0, Pass = 31, Failed!

Randomly chosen plot is at 38, 17

Validity = 0

Player ID = 0, Pass = 32, Failed!

Randomly chosen plot is at 39, 10

Validity = 0

Player ID = 0, Pass = 33, Failed!

Randomly chosen plot is at 16, 22

Validity = 0

Player ID = 0, Pass = 34, Failed!

Randomly chosen plot is at 16, 22

Validity = 0

Player ID = 0, Pass = 35, Failed!

Randomly chosen plot is at 36, 26

Validity = 0

Player ID = 0, Pass = 36, Failed!

Randomly chosen plot is at 2, 24

Validity = 0

Player ID = 0, Pass = 37, Failed!

Randomly chosen plot is at 39, 10

Validity = 0

Player ID = 0, Pass = 38, Failed!

Randomly chosen plot is at 16, 22

Validity = 0

Player ID = 0, Pass = 39, Failed!

Randomly chosen plot is at 46, 4

Validity = 0

Player ID = 0, Pass = 40, Failed!

Randomly chosen plot is at 6, 5

Validity = 0

Player ID = 0, Pass = 41, Failed!

Randomly chosen plot is at 46, 4

Validity = 0

Player ID = 0, Pass = 42, Failed!

Randomly chosen plot is at 9, 27

Validity = 0

Player ID = 0, Pass = 43, Failed!

Randomly chosen plot is at 17, 15

Validity = 1

Adding player starting city to 17, 15
[Between these two CvGameInterface and CvGameUtils are loaded, and the BUG game utils event bindings happen]
Plot selection has failed horribly! Manually creating solar system

Checking for player 1 in

[0]

Solar System Plot List is of size 13

Randomly chosen plot is at 23, 20

Validity = 0

Player ID = 1, Pass = 0, Failed!

Randomly chosen plot is at 16, 22

Validity = 0

Player ID = 1, Pass = 1, Failed!

Randomly chosen plot is at 39, 10

Validity = 0

Player ID = 1, Pass = 2, Failed!

Randomly chosen plot is at 46, 4

Validity = 0

Player ID = 1, Pass = 3, Failed!

Randomly chosen plot is at 9, 27

Validity = 0

Player ID = 1, Pass = 4, Failed!

Randomly chosen plot is at 23, 20

Validity = 0

Player ID = 1, Pass = 5, Failed!

Randomly chosen plot is at 6, 5

Validity = 0

Player ID = 1, Pass = 6, Failed!

Randomly chosen plot is at 2, 24

Validity = 0

Player ID = 1, Pass = 7, Failed!

Randomly chosen plot is at 39, 10

Validity = 0

Player ID = 1, Pass = 8, Failed!

Randomly chosen plot is at 6, 5

Validity = 0

Player ID = 1, Pass = 9, Failed!

Randomly chosen plot is at 16, 22

Validity = 0

Player ID = 1, Pass = 10, Failed!

Randomly chosen plot is at 2, 24

Validity = 0

Player ID = 1, Pass = 11, Failed!

Randomly chosen plot is at 36, 26

Validity = 0

Player ID = 1, Pass = 12, Failed!

Randomly chosen plot is at 46, 11

Validity = 0

Player ID = 1, Pass = 13, Failed!

Randomly chosen plot is at 6, 5

Validity = 0

Player ID = 1, Pass = 14, Failed!

Randomly chosen plot is at 16, 22

Validity = 0

Player ID = 1, Pass = 15, Failed!

Randomly chosen plot is at 2, 24

Validity = 0

Player ID = 1, Pass = 16, Failed!

Randomly chosen plot is at 46, 4

Validity = 0

Player ID = 1, Pass = 17, Failed!

Randomly chosen plot is at 21, 6

Validity = 0

Player ID = 1, Pass = 18, Failed!

Randomly chosen plot is at 38, 17

Validity = 0

Player ID = 1, Pass = 19, Failed!

Randomly chosen plot is at 38, 17

Validity = 0

Player ID = 1, Pass = 20, Failed!

Randomly chosen plot is at 21, 6

Validity = 0

Player ID = 1, Pass = 21, Failed!

Randomly chosen plot is at 2, 24

Validity = 0

Player ID = 1, Pass = 22, Failed!

Randomly chosen plot is at 21, 6

Validity = 0

Player ID = 1, Pass = 23, Failed!

Randomly chosen plot is at 2, 24

Validity = 0

Player ID = 1, Pass = 24, Failed!

Randomly chosen plot is at 16, 22

Validity = 0

Player ID = 1, Pass = 25, Failed!

Randomly chosen plot is at 9, 27

Validity = 0

Player ID = 1, Pass = 26, Failed!

Randomly chosen plot is at 6, 5

Validity = 0

Player ID = 1, Pass = 27, Failed!

Randomly chosen plot is at 23, 20

Validity = 0

Player ID = 1, Pass = 28, Failed!

Randomly chosen plot is at 46, 4

Validity = 0

Player ID = 1, Pass = 29, Failed!

Randomly chosen plot is at 21, 6

Validity = 0

Player ID = 1, Pass = 30, Failed!

Randomly chosen plot is at 39, 10

Validity = 0

Player ID = 1, Pass = 31, Failed!

Randomly chosen plot is at 38, 17

Validity = 0

Player ID = 1, Pass = 32, Failed!

Randomly chosen plot is at 9, 27

Validity = 0

Player ID = 1, Pass = 33, Failed!

Randomly chosen plot is at 39, 10

Validity = 0

Player ID = 1, Pass = 34, Failed!

Randomly chosen plot is at 9, 27

Validity = 0

Player ID = 1, Pass = 35, Failed!

Randomly chosen plot is at 9, 18

Validity = 0

Player ID = 1, Pass = 36, Failed!

Randomly chosen plot is at 16, 22

Validity = 0

Player ID = 1, Pass = 37, Failed!

Randomly chosen plot is at 21, 6

Validity = 0

Player ID = 1, Pass = 38, Failed!

Randomly chosen plot is at 46, 11

Validity = 0

Player ID = 1, Pass = 39, Failed!

Randomly chosen plot is at 9, 27

Validity = 0

Player ID = 1, Pass = 40, Failed!

Randomly chosen plot is at 21, 6

Validity = 0

Player ID = 1, Pass = 41, Failed!

Randomly chosen plot is at 46, 4

Validity = 0

Player ID = 1, Pass = 42, Failed!

Randomly chosen plot is at 49, 18

Validity = 0

Player ID = 1, Pass = 43, Failed!

Randomly chosen plot is at 49, 18

Validity = 0

Player ID = 1, Pass = 44, Failed!

Randomly chosen plot is at 49, 18

Validity = 0

Player ID = 1, Pass = 45, Failed!

Randomly chosen plot is at 9, 18

Validity = 0

Player ID = 1, Pass = 46, Failed!

Randomly chosen plot is at 36, 26

Validity = 1

Adding player starting city to 36, 26

Plot selection has failed horribly! Manually creating solar system

Checking for player 2 in

[0, 1]

Solar System Plot List is of size 12

Randomly chosen plot is at 46, 4

Validity = 0

Player ID = 2, Pass = 0, Failed!

Randomly chosen plot is at 9, 27

Validity = 0

Player ID = 2, Pass = 1, Failed!

Randomly chosen plot is at 9, 27

Validity = 0

Player ID = 2, Pass = 2, Failed!

Randomly chosen plot is at 9, 18

Validity = 0

Player ID = 2, Pass = 3, Failed!

Randomly chosen plot is at 23, 20

Validity = 0

Player ID = 2, Pass = 4, Failed!

Randomly chosen plot is at 9, 27

Validity = 0

Player ID = 2, Pass = 5, Failed!

Randomly chosen plot is at 46, 4

Validity = 0

Player ID = 2, Pass = 6, Failed!

Randomly chosen plot is at 16, 22

Validity = 0

Player ID = 2, Pass = 7, Failed!

Randomly chosen plot is at 46, 4

Validity = 0

Player ID = 2, Pass = 8, Failed!

Randomly chosen plot is at 21, 6

Validity = 0

Player ID = 2, Pass = 9, Failed!

Randomly chosen plot is at 46, 11

Validity = 0

Player ID = 2, Pass = 10, Failed!

Randomly chosen plot is at 2, 24

Validity = 0

Player ID = 2, Pass = 11, Failed!

Randomly chosen plot is at 6, 5

Validity = 0

Player ID = 2, Pass = 12, Failed!

Randomly chosen plot is at 23, 20

Validity = 0

Player ID = 2, Pass = 13, Failed!

Randomly chosen plot is at 2, 24

Validity = 0

Player ID = 2, Pass = 14, Failed!

Randomly chosen plot is at 2, 24

Validity = 0

Player ID = 2, Pass = 15, Failed!

Randomly chosen plot is at 9, 18

Validity = 0

Player ID = 2, Pass = 16, Failed!

Randomly chosen plot is at 21, 6

Validity = 0

Player ID = 2, Pass = 17, Failed!

Randomly chosen plot is at 9, 27

Validity = 0

Player ID = 2, Pass = 18, Failed!

Randomly chosen plot is at 16, 22

Validity = 0

Player ID = 2, Pass = 19, Failed!

Randomly chosen plot is at 38, 17

Validity = 0

Player ID = 2, Pass = 20, Failed!

Randomly chosen plot is at 23, 20

Validity = 0

Player ID = 2, Pass = 21, Failed!

Randomly chosen plot is at 16, 22

Validity = 0

Player ID = 2, Pass = 22, Failed!

Randomly chosen plot is at 39, 10

Validity = 0

Player ID = 2, Pass = 23, Failed!

Randomly chosen plot is at 23, 20

Validity = 0

Player ID = 2, Pass = 24, Failed!

Randomly chosen plot is at 39, 10

Validity = 0

Player ID = 2, Pass = 25, Failed!

Randomly chosen plot is at 16, 22

Validity = 0

Player ID = 2, Pass = 26, Failed!

Randomly chosen plot is at 46, 11

Validity = 0

Player ID = 2, Pass = 27, Failed!

Randomly chosen plot is at 38, 17

Validity = 0

Player ID = 2, Pass = 28, Failed!

Randomly chosen plot is at 39, 10

Validity = 0

Player ID = 2, Pass = 29, Failed!

Randomly chosen plot is at 9, 18

Validity = 0

Player ID = 2, Pass = 30, Failed!

Randomly chosen plot is at 6, 5

Validity = 0

Player ID = 2, Pass = 31, Failed!

Randomly chosen plot is at 9, 27

Validity = 0

Player ID = 2, Pass = 32, Failed!

Randomly chosen plot is at 46, 11

Validity = 0

Player ID = 2, Pass = 33, Failed!

Randomly chosen plot is at 2, 24

Validity = 0

Player ID = 2, Pass = 34, Failed!

Randomly chosen plot is at 46, 4

Validity = 0

Player ID = 2, Pass = 35, Failed!

Randomly chosen plot is at 2, 24

Validity = 0

Player ID = 2, Pass = 36, Failed!

Randomly chosen plot is at 46, 11

Validity = 0

Player ID = 2, Pass = 37, Failed!

Randomly chosen plot is at 21, 6

Validity = 0

Player ID = 2, Pass = 38, Failed!

Randomly chosen plot is at 21, 6

Validity = 0

Player ID = 2, Pass = 39, Failed!

Randomly chosen plot is at 6, 5

Validity = 0

Player ID = 2, Pass = 40, Failed!

Randomly chosen plot is at 9, 18

Validity = 0

Player ID = 2, Pass = 41, Failed!

Randomly chosen plot is at 46, 11

Validity = 1

Adding player starting city to 46, 11

Plot selection has failed horribly! Manually creating solar system

Checking for player 0 in

[0, 1, 2]

pStartPlot is already assigned to 17, 15

Checking for player 1 in

[1, 2]

pStartPlot is already assigned to 36, 26

Checking for player 2 in

[2]

pStartPlot is already assigned to 46, 11

Here is my current version of FFMapscriptCore:

Code:
#By TC01 for Final Frontier Plus

"""Final Frontier Mapscript Code

FFMapscriptCore contains all functions that are universal to all FF mapscripts.
The main one is starting plot selection, but others may be added too.

If you have changed a function from the default FinalFrontier mapscript, don't
use the default here. These are all based on the code in FinalFrontier.py"""

from CvPythonExtensions import *
import CvUtil
import CvMapGeneratorUtil
from CvSolarSystem import *

import random
import sys

gc = CyGlobalContext()

g_apSolarSystemPlotList = []
g_aiPickedPlotForPlayer = []

def FinalFrontier_findStartingPlot(argsList):
	"""FinalFrontier.py version of findStartingPlot(), only use if you have not modified this function."""
	
	[iPlayer] = argsList
	iStartPlotNum = -1
	iFeatureSolarSystem = gc.getInfoTypeForString(gc.getDefineSTRING("SOLAR_SYSTEM"))
	
	printd("Checking for player %d in" %(iPlayer))
	printd(g_aiPickedPlotForPlayer)
	
	# Don't find a starting location more than once for a player
	if (iPlayer in g_aiPickedPlotForPlayer):
		pStartPlot = gc.getPlayer(iPlayer).getStartingPlot()
		printd("pStartPlot is already assigned to %d, %d" %(pStartPlot.getX(), pStartPlot.getY()))
		iPlotNum = CyMap().plotNum(pStartPlot.getX(), pStartPlot.getY())
		
		# Reset lists... would do this elsewhere but it appears there are multiple instances of these arrays floating around so I have to clear them in this function it seems
		g_aiPickedPlotForPlayer.remove(iPlayer)
		global g_apSolarSystemPlotList
		g_apSolarSystemPlotList = []

		return iPlotNum
	
	printd("Solar System Plot List is of size %d" %(len(g_apSolarSystemPlotList)))
	
	# Make list of valid plots (Solar Systems), but only once
	if (len(g_apSolarSystemPlotList) == 0):
		for iPlotLoop in range(CyMap().numPlots()):
			pPlot = CyMap().plotByIndex(iPlotLoop)
			if (pPlot.getFeatureType() == iFeatureSolarSystem):
				g_apSolarSystemPlotList.append(pPlot)
	
	# Now pick a random solar system from this list to see if it should become the player's start location
	iNumSolarSystems = len(g_apSolarSystemPlotList)
	pPlayer = gc.getPlayer(iPlayer)
	iRange = pPlayer.startingPlotRange()
	iPass = 0
	
	# Loop until we find a valid plot
	while (true):
		iRand = CyGame().getSorenRandNum(iNumSolarSystems, "Picking random solar system to start at for player %d" %(iPlayer))
		pRandomPlot = g_apSolarSystemPlotList[iRand]
		printd("Randomly chosen plot is at %d, %d" %(pRandomPlot.getX(), pRandomPlot.getY()))
		bValid = True
		
		# See if the random Solar System is too close to another player's start
		for iClosePlayerLoop in range(gc.getMAX_CIV_PLAYERS()):
			if (gc.getPlayer(iClosePlayerLoop).isAlive()):
				if (iClosePlayerLoop != iPlayer):
					if startingPlotWithinRange(gc.getPlayer(iClosePlayerLoop), pRandomPlot, iPlayer, iRange, iPass):
						bValid = False
						break
		
		printd("Validity = %d" % (int(bValid)))
		
		# The one we've picked isn't too close, so use it
		if (bValid):
			iStartPlotNum = CyMap().plotNum(pRandomPlot.getX(), pRandomPlot.getY())
			g_apSolarSystemPlotList.remove(pRandomPlot)		# Now remove the plot from the list of valid Solar Systems which players can start at
			g_aiPickedPlotForPlayer.append(iPlayer)			# This player has now been assigned a starting plot, so this array tells the game not to do it again
			
			# Remove nearby goody huts
			for iXLoop in range(pRandomPlot.getX()-1, pRandomPlot.getX()+2):
				for iYLoop in range(pRandomPlot.getY()-1, pRandomPlot.getY()+2):
					iActiveX = iXLoop
					iActiveY = iYLoop
					if (iActiveX < 0):
						iActiveX = CyMap().getGridWidth() + iActiveX
					if (iActiveY < 0):
						iActiveY = CyMap().getGridHeight() + iActiveY
					pLoopPlot = CyMap().plot(iActiveX, iActiveY)
					# Any improvement? At this point it would only be a goody hut
					if (pLoopPlot.getImprovementType() != -1):
						pLoopPlot.setImprovementType(-1)
			
			#Add capital city, with capitol buildingclass, and then add starting units
			printd("Adding player starting city to %d, %d" %(pRandomPlot.getX(), pRandomPlot.getY()))
			pPlayer.initCity(pRandomPlot.getX(), pRandomPlot.getY())
			pCity = pRandomPlot.getPlotCity()
			
			pCiv = gc.getCivilizationInfo(pPlayer.getCivilizationType())
			
			#Find the capitol unit class and add it
			iCapitolClass = gc.getInfoTypeForString(gc.getDefineSTRING("FF_PALACE_BUILDINGCLASS"))
			iCapitol = pCiv.getCivilizationBuildings(iCapitolClass)
			pCity.setNumRealBuilding(iCapitol, 1)
			
			#Find starting player unit classes and add them
			if (pPlayer.getNumUnits() == 0):
				for iUnitClass in range(gc.getNumUnitClassInfos()):
					iUnit = pCiv.getCivilizationUnits(iUnitClass)
					iNumUnits = pCiv.getCivilizationFreeUnitsClass(iUnitClass)
					if iNumUnits > 0:
						for i in range(iNumUnits):
							pPlayer.initUnit(iUnit, pRandomPlot.getX(), pRandomPlot.getY(), UnitAITypes.NO_UNITAI, DirectionTypes.NO_DIRECTION)
			
			#If the entire thing has failed horribly and there is no solar system for the city, create one
			if pRandomPlot.getFeatureType() != iFeatureSolarSystem:
				printd("Plot selection has failed horribly! Manually creating solar system")
				pRandomPlot.setFeatureType(iFeatureSolarSystem, 0)
				
			break		# We're done searching, exit the while loop
			
		# This run has failed to find a starting plot far enough away, try another random plot
		printd("Player ID = %d, Pass = %d, Failed!" % (iPlayer, iPass))
		iPass += 1

	#Return iStartPlotNum
	return iStartPlotNum


def startingPlotWithinRange(pPlayer, pPlot, iOtherPlayer, iRange, iPass):
	"""FinalFrontier.py standard utility function."""
	iRange -= iPass
	pStartingPlot = pPlayer.getStartingPlot()
	
	if (pStartingPlot != -1):
		if (CyGame().isTeamGame()):
			if (gc.getPlayer(iOtherPlayer).getTeam() == pPlayer.getTeam()):
				iRange *= gc.getDefineINT("OWN_TEAM_STARTING_MODIFIER")
				iRange /= 100
			else:
				iRange *= gc.getDefineINT("RIVAL_TEAM_STARTING_MODIFIER")
				iRange /= 100
		if (plotDistance(pPlot.getX(), pPlot.getY(), pStartingPlot.getX(), pStartingPlot.getY()) <= iRange):
			return true

	return false

And here is the findStartingPlot function in FinalFrontier:

Code:
def findStartingPlot(argsList):
	#Call function in FFMapscriptCore
	iStartPlotNum = FFMapscriptCore.FinalFrontier_findStartingPlot(argsList)
	return iStartPlotNum
 
I suspect this is like a problem I had. I'm nearly certain it is the same problem.

I found that it is not that cities are not generated on solar system plots. It is that cities are wiping out the solar system feature. This is like how they wipe out a forest, jungle, or floodplain feature in regular BtS when you found a city on top of one.

To fix this, I modified the file BugGameUtils.py (in Python\BUG) to change the default for citiesDestroyFeatures from True to False. The file from my beta should have a "#FFP" comment at the end of the line that I changed.

In regular FF (and BUGless FFP) this is controlled by the citiesDestroyFeatures function in CvGameUtils.py which returns False (whereas in regular BtS it is set to return True). For some unknown reason even though the citiesDestroyFeatures function in FinalFrontierGameUtils.py in the FFPBUG beta returns False it still destroys the feature unless you change the default definition in BugGameUtils.py.

By the way - to make sure you have all the modifications I did to the BUG files, you might want to check for files in the FFPBUG beta that have modification dates after the first of October of 2010 - BUG 4.4 itself has no files modified after that and I started the merge well after that so that should catch them all - I think it may have been November 9th, actually (so you could start the search at 1-November).

It also turns out that I was not 100% diligent in marking everything I changed with an "FFP" or "Final Frontier Plus" comment. That is why you may want to do the search. I know that the TraitUtil.py file has no such marker in it, but I did modify it by adding the FF traits to the list. (With a lot of luck that might be the only one not marked - but if there is one, there could easily be more...) There may also be parts of files with the marker that were changed byt not marked - I know of one such case: in the main BUG init.xml file there is a section where "Final Frontier Plus" shows up in a comment marking where the mod is loaded but there is another line just below that in the next section, the screen section, where the FFPOption page is added as the first page in the BUG options screen.

I really should have been more careful with marking my changes. 95% (or whatever) is not what I was aiming for.

It occurs to me that Win Merge can do a difference on all files in a folder ant tell you which ones are in one folder or the other and which of the matching files by name are different. Using that to compare the FFPBUG files with the BUG files could be the way to go. It'll tell you which ones are unchanged and which ones are actually different.
 
Aha.

I ran WinMerge over Python/, Python/EntryPoints, Python/Interface, Python/pyWB: anything I thought I might have changed between 1.651 and my working copy. I neglected to do so between your BUG files and the BUG 4.4 stock ones.

Thanks!
 
I don't know what I was thinking...

There is a much easier way to tell which files I modified. The Beta and patch(es) .zip files only include the files that were changed from FFP and BUG. Any that are in there are modified from the versions in either FFP or BUG.
 
It takes a reboot to change the civilopedia. Is there a way to change that?

Other than that, everything has worked well in my test game so far. Mind you, I'm only 100 turns along or so.
 
I hope you don't mean rebooting the computer...

I can't say that I've ever hand any real problem with that. I normally exit the game completely before making changes and then start it up again after I change anything, and that seems to work just fine.
 
I hope you don't mean rebooting the computer...

I can't say that I've ever hand any real problem with that. I normally exit the game completely before making changes and then start it up again after I change anything, and that seems to work just fine.

Heh, no. Restarting Civ.

And I meant disabling it in-game using the BUG control-alt-o options menu, if that wasn't clear.
 
I don't think there is anything you can do about that. As I recall, the regular civilopedia and the sevopedia settings make it load different sets of Python files rather than activating things via conditional statements in the same files. I expect that all that stuff is only checked when loading the game.

Sounds like things are coming along nicely. Any guess at a release date yet?

By the way, I noticed a while back that FFP broke into the top fifty downloads here. It's been at #49 for at least a couple of months now and is creeping up on #48 (a MOO2Civ patch from 2 years ago), currently exactly 100 downloads behind it. The FFPBUG beta 1 attachment has 61 downloads and Patch 2 has 44 - which is much better than the "maybe 20" I was thinking the beta would get when I released it. In spite of the low level of feedback that we get, FFP is apparently pretty popular. I know BUG is very popular. Because of that, I wonder what the BUGification of FFP will do to the download count. Most of the people who play it are likely to update to the new version, but it might bring in some additional BUG fans too.
 
I don't think there is anything you can do about that. As I recall, the regular civilopedia and the sevopedia settings make it load different sets of Python files rather than activating things via conditional statements in the same files. I expect that all that stuff is only checked when loading the game.

Oh well then.

Sounds like things are coming along nicely. Any guess at a release date yet?

By the way, I noticed a while back that FFP broke into the top fifty downloads here. It's been at #49 for at least a couple of months now and is creeping up on #48 (a MOO2Civ patch from 2 years ago), currently exactly 100 downloads behind it. The FFPBUG beta 1 attachment has 61 downloads and Patch 2 has 44 - which is much better than the "maybe 20" I was thinking the beta would get when I released it. In spite of the low level of feedback that we get, FFP is apparently pretty popular. I know BUG is very popular. Because of that, I wonder what the BUGification of FFP will do to the download count. Most of the people who play it are likely to update to the new version, but it might bring in some additional BUG fans too.

Actually, I'm releasing it once I finish writing this post. ;)

I ran a test game through to turn 400 using AI Auto Play as a brute force check for Python exceptions. None came up, and whenever I checked in on the test game everything was seeming to work fine. I also started a game and got it to around turn 150, at which point I realized that it would probably be better to release now and patch over the next week or so then delay release any further. (Since 1.7 has waited for so long).

Maybe we should set up a play tester system like some big mods (Rise from Erebus for example) do.

Nice to see the downloads though! We should easily beat that old MOO2Civ release once I upload this. It's also going to go up one once I delete the patch download that somehow got 12651 downloads- when the actual mod only got 6415 since 1.0 and the release on WPC has only gotten 4687, again since 1.2 when I started offering it.
 
OK, i've had another couple of errors.

the first error is related to unit naming which I think I may be able to fix myself if I can find the right file. Screen shots show all error messages received.

View attachment 298898View attachment 298899View attachment 298900View attachment 298901View attachment 298902View attachment 298903View attachment 298904

The last error message I had, killed the game in progress when I built my first starbase.

View attachment 298905

Hoping you can provide answers to the problems I have experienced.
 
Going through these one at a time...

Hi guys, as stated on the B5 developement thread here are the screen shots of the error messages experienced so far.

The first screen shot is from the civilopedia when I selected the Traits.

View attachment 298884

For each trait you have added you need to add an entry in XML\BasicInfos\CIV4NewConceptInfos.xml. For each trait you remove, you also have to remove (or disable via commenting) the entry for that trait in that file. I think you have one, or more, entries for traits you do not actually have in your mod (in the CIV4TraitInfos.xml file).

The entries for the traits also have to be in alphabetical order, by Type tag. They also need to be in the trait section of the file and use a Type value that fits the format "CONCEPT_" + the type tag for the trait in CIV4TraitInfos.xml, just like the entries in the file already.
 
The next four screen shots are from the opening turn of the game when you start playing.

View attachment 298885 View attachment 298889 View attachment 298886 View attachment 298887

Instead of posting the series of screenshots to show the one line at a time error messages, the contents of the python error log would probably be better.

Anyhow, it looks like you have a unit class that has a default unit specified that does not exist.

My first guess is that you probably use the value NONE in the unit class, then in the civilization files it has one or more civilizations that get a unit type assigned to that unit class (making it a unique unit for them). This is the easy way to make an entire unit class unique to some subset of civs. But BUG apparently doesn't like it.

If you are not using a default unit type of NONE from some unit class, then you need to check them to make sure that the specified unit types are all valid.

If you are using a default unit type of NONE for some unit class the fix would need to be one of two things:
A) Use the other method for doing this, which apparently BUG wants you to use: give the class a valid default unit and add an entry for each civ that doesn't get a unit of that class which specifies the unit type of NONE.

or

B) (A solution which might lead to other problems in the BUG code that need fixing) Modify the file Python\BUG\UnitUtil.py by changing the code around line 73 from this:
Code:
		else:
			BugUtil.debug("  unique of %s",
					gc.getUnitInfo(eGenericUnit).getDescription())
to something like this:
Code:
		else:
			if eGenericUnit != -1:
				BugUtil.debug("  unique of %s",
					gc.getUnitInfo(eGenericUnit).getDescription
())
			else:
				BugUtil.debug("  unique of NONE")

Note: I have not tried this code change. It is possible that somewhere else in BUG there is code that does not like unit classes to have default unit types of NONE. That would lead to more changes in the BUG code being needed (or switching to fix A).
 
OK, i've had another couple of errors.

the first error is related to unit naming which I think I may be able to fix myself if I can find the right file. Screen shots show all error messages received.

View attachment 298898View attachment 298899View attachment 298900View attachment 298901View attachment 298902View attachment 298903View attachment 298904

The file Assets\Config\Unit Naming.xml needs to be modified so that the option values match the unit combat types for your mod. You should adjust both the id and the key values (one option tag per unitcombat type).

After doing that, you should delete the file UserSettings\Unit Naming.ini and run the game. BUG will create a new version of that file with all of the settings set to their specified default value.

Also, you will want to completely change the contents of the file UserSettings\Adv Unit Naming.ini. This file controls the unit names when the BUG option for "advanced unit naming" is turned on. It contains a lot of entries, one for each unit class in each era.
In this file, the first part (before the "=") is the ID for the name which consists of the era name then the unit class, like "ISOLATION_COLONY_SHIP" for the unit of class UNITCLASS_COLONY_SHIP in the era ERA_ISOLATION.
The second part (after the "=") is the text used for the unit name using the unit naming code that is specified in the (hard to read due to xml formatting tags) comments in the Unit Naming.ini file.
The ship name format that is currently in there goes like this: "Colony Ship ^cnt[n]^ (^ct^)" where "Colony Ship" is plain text that will be used - the values I picked are (aside from this particular bad example of the Colony Ship) shorter than the actual ship class's name (such as "BB" for "Battleship"), followed by "^cnt[n]^" which gives a count of all units of this class you have ever produced including this one (giving each a unique number), and finishing with "(^ct^)" which gives the name of the city where the unit was produced. This produces a name that is the same format as the "non-advanced" unit naming string used by BUG (if the unit naming feature is active) but shorter due to the manual selection of shorter names for the unit classes (like the "BB" for "Battleship"), so the default unit naming might produce "Battleship 3 (New Earth)" the advanced version is "BB-3 (New Earth)".
 
The last error message I had, killed the game in progress when I built my first starbase.

View attachment 298905

This one has been stumping me for a while. I have added code to try to avoid it and it happens less (it has not happened to me in the last 4, r so, games I have played)but it does, evidently, still happen.

The number of times that error message pops up is large but apparently finite so you can eventually click through them all. Or, at least, if you are playing in full screen mode and go to the desktop (or some other application) and then go back to the game it will no longer be generating any more of them (still leaving you with a bunch to click through).

As far as I have noticed, it only happens if there is either another unit on the plot that is currently selected or possibly if the construction ship is currently selected at the time if finishes the starbase construction. It boils down to the puzzling question of "when is a dead unit not a dead unit?" The code has checks for this but it is sill apparently trying to draw the button down along the bottom of the screen for the not fully dead construction ship.

Check the file Python\Screens\PLE.py. It should have a modification date from this year and there should be a comment on line 290 that says "# G-E bugfix - don't show dead units".

To date, my fixes have been up in the updatePlotListButtons_PLE function (on the line with the comment, I added the two "and not" conditions), trying to get it to not call the displayUnitPlotListObjects for the dead unit. I now beleive I need to put an additional check in displayUnitPlotListObjects to break up that line 1390 where it is trying to get the button for a now apparently undead unit (yes, we are evidently afflicted with the occasional zombie) to make getting the unit info a separate call (loading it into a new variable) as the first thing in the function and then testing it to make sure it is valid (just bailing out of this function if it is invalid), well before trying to call its getButton method.
 
Going through these one at a time...



For each trait you have added you need to add an entry in XML\BasicInfos\CIV4NewConceptInfos.xml. For each trait you remove, you also have to remove (or disable via commenting) the entry for that trait in that file. I think you have one, or more, entries for traits you do not actually have in your mod (in the CIV4TraitInfos.xml file).

The entries for the traits also have to be in alphabetical order, by Type tag. They also need to be in the trait section of the file and use a Type value that fits the format "CONCEPT_" + the type tag for the trait in CIV4TraitInfos.xml, just like the entries in the file already.

Many thanks God-Emperor, this one has now been fixed.
 
Fixed, took a long time to do thos
The file Assets\Config\Unit Naming.xml needs to be modified so that the option values match the unit combat types for your mod. You should adjust both the id and the key values (one option tag per unitcombat type).

After doing that, you should delete the file UserSettings\Unit Naming.ini and run the game. BUG will create a new version of that file with all of the settings set to their specified default value.

Also, you will want to completely change the contents of the file UserSettings\Adv Unit Naming.ini. This file controls the unit names when the BUG option for "advanced unit naming" is turned on. It contains a lot of entries, one for each unit class in each era.
In this file, the first part (before the "=") is the ID for the name which consists of the era name then the unit class, like "ISOLATION_COLONY_SHIP" for the unit of class UNITCLASS_COLONY_SHIP in the era ERA_ISOLATION.
The second part (after the "=") is the text used for the unit name using the unit naming code that is specified in the (hard to read due to xml formatting tags) comments in the Unit Naming.ini file.
The ship name format that is currently in there goes like this: "Colony Ship ^cnt[n]^ (^ct^)" where "Colony Ship" is plain text that will be used - the values I picked are (aside from this particular bad example of the Colony Ship) shorter than the actual ship class's name (such as "BB" for "Battleship"), followed by "^cnt[n]^" which gives a count of all units of this class you have ever produced including this one (giving each a unique number), and finishing with "(^ct^)" which gives the name of the city where the unit was produced. This produces a name that is the same format as the "non-advanced" unit naming string used by BUG (if the unit naming feature is active) but shorter due to the manual selection of shorter names for the unit classes (like the "BB" for "Battleship"), so the default unit naming might produce "Battleship 3 (New Earth)" the advanced version is "BB-3 (New Earth)".


Another fix implemented.
 
Yeah, making the advanced unit naming file was lone and tedious to get the first era done. After that is was mostly cutting and pasting, just changing the era prefix, since I had the unit names stay the same across the eras.

Ah, the glamorous life of the modder. Filled with hours of copying stuff from one file and pasting it into another.
 
Back
Top Bottom