def retargetImmigrant(self, objUnit):
# Return immediately if the unit passed in is invalid
if(objUnit == None):
return
# Return immediately if the unit passed in is invalid
if(objUnit.isNone()):
return
# Return if the unit isn't an immigrant
if(objUnit.getUnitType() != gc.getInfoTypeForString("UNIT_IMMIGRANT")):
return
iPlayerID = objUnit.getOwner()
# Setup the civilization immigration data if it doesn't exist
if(not sdEntityExists("Immigration Mod", iPlayerID)):
self.setupImmigrantData(iPlayerID)
# Get the civilization immigration data
civilizationImmigrationHash = sdGetVal("Immigration Mod", str(iPlayerID), CIVILIZATION_IMMIGRATION_DATA)
civilizationImmigrantHash = civilizationImmigrationHash[CIVILIZATION_IMMIGRANT_HASH]
# get the immigrant data hash in the civilization immigration hash
[COLOR="Blue"] immigrantDataHash = civilizationImmigrantHash[objUnit.getID()][/COLOR]
(iX, iY) = immigrantDataHash[TARGET_PLOT].split("-")
objUnit.getGroup().clearMissionQueue()
# Make the immigrants move towards the intended target city
objUnit.getGroup().pushMoveToMission(int(iX), int(iY))
immigrantDataHash = civilizationImmigrantHash[objUnit.getID()]
immigrantDataHash = civilizationImmigrantHash[str(objUnit.getID())]
The error means basically: "I'm searching for a value, and can't find it".
If you take a look at the mentioned line:
PHP:immigrantDataHash = civilizationImmigrantHash[objUnit.getID()]
...do you remember something? Yes, it's related to the last change.
In the last change, we've converted an ID to a string value (from being an integer before).
Now here, the game is asking the "saving structure" for a value, and gives it an ID...an integer, but wait, we converted the integer before to a string!
...er...i guess that was now confusing.
So long explanation short, change the problematic line to
PHP:immigrantDataHash = civilizationImmigrantHash[str(objUnit.getID())]
d[key]
Return the item of d with key key. Raises a KeyError if key is not in the map.
The previous issue does not appear to have anything to do with this one. They are not referring to the same dictionary.
def removeImmigrantData(self, objUnit):
# Return immediately if the unit passed in is invalid
if(objUnit == None):
return
# Return immediately if the unit passed in is invalid
if(objUnit.isNone()):
return
# Get the owner of the unit
iPlayerID = objUnit.getOwner()
# Setup the player's game data if it doesn't exist and return immediately
if(not sdEntityExists("Immigration Mod", iPlayerID)):
self.setupImmigrantData(iPlayerID)
return
# Get the civilization immigration data
civilizationImmigrationHash = sdGetVal("Immigration Mod", iPlayerID, CIVILIZATION_IMMIGRATION_DATA)
# Decrement the immigrant count for the civilization
civilizationImmigrationHash[CIVILIZATION_IMMIGRATION_COUNT] -= 1
# Delete the immigrant data from the civilization hash
del civilizationImmigrationHash[CIVILIZATION_IMMIGRANT_HASH][objUnit.getID()]
# Save the updated civiliation immigration hash
sdSetVal("Immigration Mod", iPlayerID, CIVILIZATION_IMMIGRATION_DATA, civilizationImmigrationHash )
# Sets up the immigration data for the player ID passed in. Returns True if
# the data was setup successfully, False otherwise.
def setupImmigrantData(self, iPlayerID):
# Get the instance of the player
objPlayer = gc.getPlayer(iPlayerID)
# Return False immediately if the player ID passed in was invalid
if( objPlayer == None):
return False
# Return False immediately if the player ID passed in was invalid
if( objPlayer.isNone()):
return False
civilizationImmigrantHash = {}
civilizationImmigrationHash = {
CIVILIZATION_IMMIGRATION_COUNT : 0,
CIVILIZATION_IMMIGRANT_HASH : civilizationImmigrantHash,
}
scriptDict = { CIVILIZATION_IMMIGRATION_DATA : civilizationImmigrationHash }
# Initialize the actual entity.
sdEntityInit("Immigration Mod", str(iPlayerID), scriptDict)
return True
def saveImmigrantData(self, objUnit, objTargetCity, objCity, cultureDataHash, immigrantReligionList, strImmigrationTargetSuggestion):
# Return immediately if the city passed in is invalid
if(objCity == None):
return
# Return immediately if the city passed in is invalid
if(objCity.isNone()):
return
# Return immediately if the target city passed in is invalid
if(objTargetCity == None):
return
# Return immediately if the target city passed in is invalid
if(objTargetCity.isNone()):
return
# Return immediately if the unit passed in is invalid
if(objUnit == None):
return
# Return immediately if the unit passed in is invalid
if(objUnit.isNone()):
return
# Return immediately if the culture data passed in is invalid
if(cultureDataHash == None):
return
# Return immediately if the religion data passed in is invalid
if(immigrantReligionList == None):
return
# Get the owner ID of the city
iPlayerID = objCity.getOwner()
# Setup the civilization immigration data if it doesn't exist
if(not sdEntityExists("Immigration Mod", iPlayerID)):
self.setupImmigrantData(iPlayerID)
# Get the civilization immigration data
civilizationImmigrationHash = sdGetVal("Immigration Mod", str(iPlayerID), CIVILIZATION_IMMIGRATION_DATA)
# Increment the immigrant count for the civilization
civilizationImmigrationHash[CIVILIZATION_IMMIGRATION_COUNT] += 1
# Construct the immigrant data hash
immigrantDataHash = {
CITY_ORIGINS : objCity.getID(),
TARGET_PLOT : str(objTargetCity.plot().getX())+"-"+str(objTargetCity.plot().getY()),
IMMIGRANT_CULTURE : cultureDataHash,
IMMIGRANT_RELIGION : immigrantReligionList,
TARGET_CITY_SUGGESTION : strImmigrationTargetSuggestion,
}
# Get the civilization immigrant hash
civilizationImmigrantHash = civilizationImmigrationHash[CIVILIZATION_IMMIGRANT_HASH]
# Save the immigrant data hash in the civilization immigration hash
civilizationImmigrantHash[objUnit.getID()] = immigrantDataHash
civilizationImmigrationHash[CIVILIZATION_IMMIGRANT_HASH] = civilizationImmigrantHash
# Save the updated civiliation immigration hash
sdSetVal("Immigration Mod", iPlayerID, CIVILIZATION_IMMIGRATION_DATA, civilizationImmigrationHash )
The thing I find most confusing, however, is why you refer to just about anything as a "hash table".What is a hash table?