Culturaly linkes start question (CvCultureLinkInterface.py)

Joined
Jul 5, 2004
Messages
23,562
Location
Canberra, Australia
I am getting the following error from CvCultureLinkInterface.py.

message:
Code:
Traceback (most recent call last):

  File "CvCultureLinkInterface", line 262, in assignCulturallyLinkedStarts

  File "CvCultureLinkInterface", line 277, in __init__

  File "CvCultureLinkInterface", line 291, in __initRWCoordinatesList

KeyError: 0
ERR: Python function assignCulturallyLinkedStarts failed, module CvCultureLinkInterface

Indicated line where error is occurring in red:

Code:
	def __initRWCoordinatesList(self):
		iNumPlayers = game.countCivPlayersEverAlive()
		for iPlayer in range(iNumPlayers):
			pPlayer = gc.getPlayer(iPlayer)
			eCivilization = pPlayer.getCivilizationType()
[COLOR="Red"]			pCoordinate = CoordinatesDictionary[eCivilization][/COLOR]
			CultureLink.pRWCoordinatesList.append(pCoordinate)

As far as I can tell it means that either one or more civs are not defined in the coordinates dictionary or they have not been defined in the enum CivilizationTypes returned by getCivilizationType().

Where is this enum CivilizationTypes defined? I assume both this code and the enum need to be updated whenever a new civ is added to a mod. Something I have never done.

Does anyone know who "owns" this code? I was thinking of putting an error message in there to give a better warning than "KeyError:0" which, I think, means that the index is out of range ie civ is not defined.
 
Not sure I understand the entire context, but CivilizationTypes is constructed from the XML.
Like many other enums in the Civ4 code it is 'empty' in the code - only contains a single value (NO_CIVILIZATION in this case, or something) with the value of -1.
The rest of the values are read in order from the XML, so 0 is the first civilization in Civ4CiviliztionInfos.xml.

In this case you should probably look for the place in which CoordinatesDictionary is filled.
 
Not sure I understand the entire context, but CivilizationTypes is constructed from the XML.
Like many other enums in the Civ4 code it is 'empty' in the code - only contains a single value (NO_CIVILIZATION in this case, or something) with the value of -1.
The rest of the values are read in order from the XML, so 0 is the first civilization in Civ4CiviliztionInfos.xml.

In this case you should probably look for the place in which CoordinatesDictionary is filled.

Good. I had hoped that the enum was generated from the XML, it makes things much easier.

I put in a proper error message and found a civ missing from the CoordinatesDictionary. Since civ selection is random I do not know if there are more until the message happens again.:)
 
Try fetching the PlayerType instead of the CivilizationType. You do this with CyPlayer.getID() - I think.
 
The problem is that the modder has forgotten to define at least one civ in the coordinate dictionary and that the error message is not that helpful. Also the error message only occurs if such a civ is chosen for the start of the game. The more civs the less likely for a particular civ to be chosen.

Now if I could figure out how to cycle over the enum and use the value to check that it exists in the dictionary. Then I could put out a reasonable set of messages for the modder.

Any one point me at how to do this? - cycle over the enum the test against the dictionary I know how to do ;)
 
I think (and Baldyr - please correct me if I'm wrong) that 'print' outputs will display in the log files:

Code:
print 'something', 4

As for the cycling - might I suggest you go over the dictionary instead? Something like:
Code:
for civId in CoordinatesDictionary.keys():
    print "Found key in CoordinatesDictionary:", civId
 
I think (and Baldyr - please correct me if I'm wrong) that 'print' outputs will display in the log files:

Code:
print 'something', 4

As for the cycling - might I suggest you go over the dictionary instead? Something like:
Code:
for civId in CoordinatesDictionary.keys():
    print "Found key in CoordinatesDictionary:", civId

Almost but the problem is that the cidId is not in CoordinatesDictionary. I am trying to tell the modder which civs they have defined in game but not in this mod.

Lets rephrase this as I am probably not explaining myself clearly. I want to help the modder, not fix the code which is fine.

The modder has defined some civs. How do I cycle over these civs to check that they have also defined the civs to the Culturally Linked Start mod? I know it is defined in the enum CivilizationType. But is there some other way of checking. from python, which civs are defined? I can find out which ones are in this current game but I want to get at all of them. That way the modder wont get a query somewher down the track when someone playing the game gets the one civ that was not defined in the 300 thet were.
 
Ah, OK.

The civilization types defined are just numbers - starting from 0 and ending with ((num of civs) - 1).
To get the num of civs you can use gc.getNumCivilizationInfos() (where gc was defined as CyGlobalContext(), usually it already happens in the beginning of the file).

And to get information about a civ you can use gc.getCivilizationInfo().

Here's an example code:
Code:
for iCiv in range(gc.getNumCivilizationInfos()):
    civ = gc.getCivilizationInfo(iCiv)
    if iCiv not in CoordinatesDictionary.keys():
        print civ.getDescription(), 'was not found in dictionary'

Didn't test it, so there might be some mistakes there.
 
That solved the problem but adds a noticeable amount of time to the init phase of the game. It also reports a "false positive" on the barbarians.

Perhaps I should just suggest to the owners of the mod that they put a bit of debugging help in their doco.
 
Top Bottom