• Our friends from AlphaCentauri2.info are in need of technical assistance. If you have experience with the LAMP stack and some hours to spare, please help them out and post here.

Event Python Question

nokmirt

Emperor
Joined
Feb 14, 2009
Messages
5,088
Location
Iowa USA
I have a vanilla mod I am working on called the The Great War. The python was written by Jon Shafer, with his permission I have added to the mod. Any way I am trying to get some reinforcement events to work. I have six reinforcement events for Britain, and they all work, except for event number three, which gives me two BASIC_LIGHT_ARTILLERY units, instead of two BRITAIN_BRITISH_MACHINEGUN units like it is supposed to. For some reason it finds artillery instead of machine gun. Here is the code.

Spoiler :
Code:
# Insert all game turn events here
#		return
		
#		print("Turn is: %d" %(iTurn))
                if (iTurn == 3 + self.iTurnOffset):#3
			self.Aug_1914()
                elif (iTurn == 5 + self.iTurnOffset):#5
			self.Sep_1914()
                elif (iTurn == 11 + self.iTurnOffset):#11
			self.Oct_1914()
                elif (iTurn == 12 + self.iTurnOffset):#12
			self.Oct_1914()
                elif (iTurn == 15 + self.iTurnOffset):#15
			self.Nov_1914()
                elif (iTurn == 17 + self.iTurnOffset):#17

##########################################################################################
####################################### TURN EVENTS #######################################
###########################################################################################

	# British send reinforcements to France
	def Aug_1914(self):
		
		aiValidCities = [	self.iCHERBOURG,	]
		
		iCityID = self.determineValidCities(self.iBritainID, aiValidCities)
		
		# If valid city exists
		if (iCityID > -1):
			
			pPlayer = gc.getPlayer(self.iBritainID)
			
			iUnitType = self.iBasicBritishInfantryID

			iCityX = pPlayer.getCity(iCityID).getX()
			iCityY = pPlayer.getCity(iCityID).getY()
			
			# Spawn unit
			pPlayer.initUnit(iUnitType, iCityX, iCityY, UnitAITypes.UNITAI_ATTACK)
			pPlayer.initUnit(iUnitType, iCityX, iCityY, UnitAITypes.UNITAI_ATTACK)
			
			# Set event text
			self.szEventText = localText.getText("TXT_KEY_WWI_EVENT_BEF_REPLACEMENTS_ONE_DESC", ())
			self.szResultText = localText.getText("TXT_KEY_WWI_EVENT_BEF_REPLACEMENTS_ONE_EFFECT", ())
			
			self.displayEventText()

        # British send reinforcements to France
	def Sep_1914(self):
		
		aiValidCities = [	self.iCHERBOURG,	]
		
		iCityID = self.determineValidCities(self.iBritainID, aiValidCities)
		
		# If valid city exists
		if (iCityID > -1):
			
			pPlayer = gc.getPlayer(self.iBritainID)
			
			iUnitType = self.iBasicBritishInfantryID

			iCityX = pPlayer.getCity(iCityID).getX()
			iCityY = pPlayer.getCity(iCityID).getY()
			
			# Spawn unit
			pPlayer.initUnit(iUnitType, iCityX, iCityY, UnitAITypes.UNITAI_ATTACK)
			
			# Set event text
			self.szEventText = localText.getText("TXT_KEY_WWI_EVENT_BEF_REPLACEMENTS_TWO_DESC", ())
			self.szResultText = localText.getText("TXT_KEY_WWI_EVENT_BEF_REPLACEMENTS_TWO_EFFECT", ())
			
			self.displayEventText()

        # British send reinforcements to France
	def Oct_1914(self):
		
		aiValidCities = [	self.iCHERBOURG,	]
		
		iCityID = self.determineValidCities(self.iBritainID, aiValidCities)
		
		# If valid city exists
		if (iCityID > -1):
			
			pPlayer = gc.getPlayer(self.iBritainID)
			
			iUnitType = self.iBritainBritishMachinegunID

			iCityX = pPlayer.getCity(iCityID).getX()
			iCityY = pPlayer.getCity(iCityID).getY()
			
			# Spawn unit
			pPlayer.initUnit(iUnitType, iCityX, iCityY, UnitAITypes.UNITAI_CITY_COUNTER)
                        pPlayer.initUnit(iUnitType, iCityX, iCityY, UnitAITypes.UNITAI_CITY_COUNTER)
			
			# Set event text
			self.szEventText = localText.getText("TXT_KEY_WWI_EVENT_BEF_REPLACEMENTS_THREE_DESC", ())
			self.szResultText = localText.getText("TXT_KEY_WWI_EVENT_BEF_REPLACEMENTS_THREE_EFFECT", ())
			
			self.displayEventText()

        # British send reinforcements to France
	def Oct_1914(self):
		
		aiValidCities = [	self.iCHERBOURG,	]
		
		iCityID = self.determineValidCities(self.iBritainID, aiValidCities)
		
		# If valid city exists
		if (iCityID > -1):
			
			pPlayer = gc.getPlayer(self.iBritainID)
			
			iUnitType = self.iBasicLightArtilleryID

			iCityX = pPlayer.getCity(iCityID).getX()
			iCityY = pPlayer.getCity(iCityID).getY()
			
			# Spawn unit
			pPlayer.initUnit(iUnitType, iCityX, iCityY, UnitAITypes.UNITAI_ATTACK_CITY)
                        pPlayer.initUnit(iUnitType, iCityX, iCityY, UnitAITypes.UNITAI_ATTACK_CITY)
			
			# Set event text
			self.szEventText = localText.getText("TXT_KEY_WWI_EVENT_BEF_REPLACEMENTS_FOUR_DESC", ())
			self.szResultText = localText.getText("TXT_KEY_WWI_EVENT_BEF_REPLACEMENTS_FOUR_EFFECT", ())
			
			self.displayEventText()

        # British send reinforcements to France
	def Nov_1914(self):
		
		aiValidCities = [	self.iCHERBOURG,	]
		
		iCityID = self.determineValidCities(self.iBritainID, aiValidCities)
		
		# If valid city exists
		if (iCityID > -1):
			
			pPlayer = gc.getPlayer(self.iBritainID)
			
			iUnitType = self.iBasicBritishInfantryID

			iCityX = pPlayer.getCity(iCityID).getX()
			iCityY = pPlayer.getCity(iCityID).getY()
			
			# Spawn unit
			pPlayer.initUnit(iUnitType, iCityX, iCityY, UnitAITypes.UNITAI_ATTACK)
                        pPlayer.initUnit(iUnitType, iCityX, iCityY, UnitAITypes.UNITAI_ATTACK)
                        pPlayer.initUnit(iUnitType, iCityX, iCityY, UnitAITypes.UNITAI_ATTACK)
                        pPlayer.initUnit(iUnitType, iCityX, iCityY, UnitAITypes.UNITAI_ATTACK)
                        pPlayer.initUnit(iUnitType, iCityX, iCityY, UnitAITypes.UNITAI_ATTACK)
                        pPlayer.initUnit(iUnitType, iCityX, iCityY, UnitAITypes.UNITAI_ATTACK)
                        pPlayer.initUnit(iUnitType, iCityX, iCityY, UnitAITypes.UNITAI_ATTACK)
                        pPlayer.initUnit(iUnitType, iCityX, iCityY, UnitAITypes.UNITAI_ATTACK)
			
			# Set event text
			self.szEventText = localText.getText("TXT_KEY_WWI_EVENT_BEF_REPLACEMENTS_FIVE_DESC", ())
			self.szResultText = localText.getText("TXT_KEY_WWI_EVENT_BEF_REPLACEMENTS_FIVE_EFFECT", ())
			
			self.displayEventText()

        # British send reinforcements to France
	def Dec_1914(self):
		
		aiValidCities = [	self.iCHERBOURG,	]
		
		iCityID = self.determineValidCities(self.iBritainID, aiValidCities)
		
		# If valid city exists
		if (iCityID > -1):
			
			pPlayer = gc.getPlayer(self.iBritainID)
			
			iUnitType = self.iBasicBritishInfantryID

			iCityX = pPlayer.getCity(iCityID).getX()
			iCityY = pPlayer.getCity(iCityID).getY()
			
			# Spawn unit
			pPlayer.initUnit(iUnitType, iCityX, iCityY, UnitAITypes.UNITAI_ATTACK)
                        pPlayer.initUnit(iUnitType, iCityX, iCityY, UnitAITypes.UNITAI_ATTACK)
                        pPlayer.initUnit(iUnitType, iCityX, iCityY, UnitAITypes.UNITAI_ATTACK)
                        pPlayer.initUnit(iUnitType, iCityX, iCityY, UnitAITypes.UNITAI_ATTACK)
                        pPlayer.initUnit(iUnitType, iCityX, iCityY, UnitAITypes.UNITAI_ATTACK)
                        pPlayer.initUnit(iUnitType, iCityX, iCityY, UnitAITypes.UNITAI_ATTACK)
                        pPlayer.initUnit(iUnitType, iCityX, iCityY, UnitAITypes.UNITAI_ATTACK)
                        pPlayer.initUnit(iUnitType, iCityX, iCityY, UnitAITypes.UNITAI_ATTACK)
			
			# Set event text
			self.szEventText = localText.getText("TXT_KEY_WWI_EVENT_BEF_REPLACEMENTS_SIX_DESC", ())
			self.szResultText = localText.getText("TXT_KEY_WWI_EVENT_BEF_REPLACEMENTS_SIX_EFFECT", ())
			
			self.displayEventText()

Here is reinforcement event three. Why would the BritainBritishMachinegunID not be recognized, and Artiilery is placed on the map at Cherbourg instead?

Spoiler :
Code:
# British send reinforcements to France
	def Oct_1914(self):
		
		aiValidCities = [	self.iCHERBOURG,	]
		
		iCityID = self.determineValidCities(self.iBritainID, aiValidCities)
		
		# If valid city exists
		if (iCityID > -1):
			
			pPlayer = gc.getPlayer(self.iBritainID)
			
			iUnitType = self.iBritainBritishMachinegunID

			iCityX = pPlayer.getCity(iCityID).getX()
			iCityY = pPlayer.getCity(iCityID).getY()
			
			# Spawn unit
			pPlayer.initUnit(iUnitType, iCityX, iCityY, UnitAITypes.UNITAI_CITY_COUNTER)
                        pPlayer.initUnit(iUnitType, iCityX, iCityY, UnitAITypes.UNITAI_CITY_COUNTER)
			
			# Set event text
			self.szEventText = localText.getText("TXT_KEY_WWI_EVENT_BEF_REPLACEMENTS_THREE_DESC", ())
			self.szResultText = localText.getText("TXT_KEY_WWI_EVENT_BEF_REPLACEMENTS_THREE_EFFECT", ())
			
			self.displayEventText()

Here is a list of the units def initValues(self):

Spoiler :
Code:
def initValues(self):
		
		self.iCavalryID =			CvUtil.findInfoTypeNum(gc.getUnitInfo,gc.getNumUnitInfos(),'WWI_UNIT_CAVALRY')#83
		self.iBasicLightArtilleryID =		CvUtil.findInfoTypeNum(gc.getUnitInfo,gc.getNumUnitInfos(),'WWI_UNIT_BASIC_LIGHT_ARTILLERY')
		self.iAdvancedLightArtilleryID =	CvUtil.findInfoTypeNum(gc.getUnitInfo,gc.getNumUnitInfos(),'WWI_UNIT_ADVANCED_LIGHT_ARTILLERY')
                self.iMachineGunID =			CvUtil.findInfoTypeNum(gc.getUnitInfo,gc.getNumUnitInfos(),'WWI_UNIT_MACHINE_GUN')
		self.iTankID =				CvUtil.findInfoTypeNum(gc.getUnitInfo,gc.getNumUnitInfos(),'WWI_UNIT_TANK')
		self.iPoisonGasID =			CvUtil.findInfoTypeNum(gc.getUnitInfo,gc.getNumUnitInfos(),'WWI_UNIT_POISON_GAS')
		self.iBiplaneID =			CvUtil.findInfoTypeNum(gc.getUnitInfo,gc.getNumUnitInfos(),'WWI_UNIT_BIPLANE')
		self.iDestroyerID =			CvUtil.findInfoTypeNum(gc.getUnitInfo,gc.getNumUnitInfos(),'WWI_UNIT_DESTROYER')
		self.iDreadnaughtID =			CvUtil.findInfoTypeNum(gc.getUnitInfo,gc.getNumUnitInfos(),'WWI_UNIT_DREADNAUGHT')
		self.iSubmarineID =			CvUtil.findInfoTypeNum(gc.getUnitInfo,gc.getNumUnitInfos(),'WWI_UNIT_SUBMARINE')
		self.iTransportID =			CvUtil.findInfoTypeNum(gc.getUnitInfo,gc.getNumUnitInfos(),'WWI_UNIT_TRANSPORT')
		
		self.iBasicInfantryID =				CvUtil.findInfoTypeNum(gc.getUnitInfo,gc.getNumUnitInfos(),'WWI_UNIT_BASIC_INFANTRY')
		self.iAdvancedInfantryID =			CvUtil.findInfoTypeNum(gc.getUnitInfo,gc.getNumUnitInfos(),'WWI_UNIT_ADVANCED_INFANTRY')
		self.iBasicGermanInfantryID =			CvUtil.findInfoTypeNum(gc.getUnitInfo,gc.getNumUnitInfos(),'WWI_UNIT_BASIC_GERMAN_INFANTRY')
		self.iAdvancedGermanInfantryID =		CvUtil.findInfoTypeNum(gc.getUnitInfo,gc.getNumUnitInfos(),'WWI_UNIT_ADVANCED_GERMAN_INFANTRY')
		self.iBasicAustroHungarianInfantryID =		CvUtil.findInfoTypeNum(gc.getUnitInfo,gc.getNumUnitInfos(),'WWI_UNIT_BASIC_AUSTRO-HUNGARIAN_INFANTRY')
		self.iAdvancedAustroHungarianInfantryID =	CvUtil.findInfoTypeNum(gc.getUnitInfo,gc.getNumUnitInfos(),'WWI_UNIT_ADVANCED_AUSTRO-HUNGARIAN_INFANTRY')
		self.iBasicOttomanInfantryID =			CvUtil.findInfoTypeNum(gc.getUnitInfo,gc.getNumUnitInfos(),'WWI_UNIT_BASIC_OTTOMAN_INFANTRY')
		self.iAdvancedOttomanInfantryID =		CvUtil.findInfoTypeNum(gc.getUnitInfo,gc.getNumUnitInfos(),'WWI_UNIT_ADVANCED_OTTOMAN_INFANTRY')
		self.iBasicRussianInfantryID =			CvUtil.findInfoTypeNum(gc.getUnitInfo,gc.getNumUnitInfos(),'WWI_UNIT_BASIC_RUSSIAN_INFANTRY')
		self.iAdvancedRussianInfantryID =		CvUtil.findInfoTypeNum(gc.getUnitInfo,gc.getNumUnitInfos(),'WWI_UNIT_ADVANCED_RUSSIAN_INFANTRY')
		self.iBasicFrenchInfantryID =			CvUtil.findInfoTypeNum(gc.getUnitInfo,gc.getNumUnitInfos(),'WWI_UNIT_BASIC_FRENCH_INFANTRY')
		self.iAdvancedFrenchInfantryID =		CvUtil.findInfoTypeNum(gc.getUnitInfo,gc.getNumUnitInfos(),'WWI_UNIT_ADVANCED_FRENCH_INFANTRY')
		self.iBasicBritishInfantryID =			CvUtil.findInfoTypeNum(gc.getUnitInfo,gc.getNumUnitInfos(),'WWI_UNIT_BASIC_BRITISH_INFANTRY')
		self.iAdvancedBritishInfantryID =		CvUtil.findInfoTypeNum(gc.getUnitInfo,gc.getNumUnitInfos(),'WWI_UNIT_ADVANCED_BRITISH_INFANTRY')
		self.iBasicItalianInfantryID =			CvUtil.findInfoTypeNum(gc.getUnitInfo,gc.getNumUnitInfos(),'WWI_UNIT_BASIC_ITALIAN_INFANTRY')
		self.iAdvancedItalianInfantryID =		CvUtil.findInfoTypeNum(gc.getUnitInfo,gc.getNumUnitInfos(),'WWI_UNIT_ADVANCED_ITALIAN_INFANTRY')
		self.iBasicAmericanInfantryID =			CvUtil.findInfoTypeNum(gc.getUnitInfo,gc.getNumUnitInfos(),'WWI_UNIT_BASIC_AMERICAN_INFANTRY')
		self.iAdvancedAmericanInfantryID =		CvUtil.findInfoTypeNum(gc.getUnitInfo,gc.getNumUnitInfos(),'WWI_UNIT_ADVANCED_AMERICAN_INFANTRY')
                self.iBritainBritishMachinegunID =			CvUtil.findInfoTypeNum(gc.getUnitInfo,gc.getNumUnitInfos(),'WWI_UNIT_BRITAIN_BRITISH_MACHINEGUN')
		
		self.iConscriptionCenterID =	CvUtil.findInfoTypeNum(gc.getBuildingInfo,gc.getNumBuildingInfos(),'WWI_BUILDING_CONSCRIPTION_CENTER')#99
		
		self.iMobileAttackDoctrineID =	CvUtil.findInfoTypeNum(gc.getTechInfo,gc.getNumTechInfos(),'WWI_TECH_MOBILE_ATTACK_DOCTRINE')
		self.iArmoredVehiclesID =	CvUtil.findInfoTypeNum(gc.getTechInfo,gc.getNumTechInfos(),'WWI_TECH_ARMORED_VEHICLES')
		
		for iPlayerLoop in range(self.iNumPlayers):
			
			pyPlayer = PyPlayer(iPlayerLoop)
			# Loop through player's cities
			apCityList = pyPlayer.getCityList()
			
			for pCityLoop in apCityList:
				
				# Initialize City
				self.initCity(pCityLoop)

If you need all the code to figure this out, please let me know and I will send it.
I backed this file up and I added every WWI unit in my mod to the def initValues(self): list, thinking that would help, but then no reinforcement events worked period. In this case with the original file, they work but it will not recognize BritainBritishMachinegunID,
instead it gives me for some odd reason a BasicLightArtilleryID. I am new to python and don't understand why.
 
No, that did not work the event did not appear.
 
I am not sure what is causing this, if anyone has any idea let me know. It seems all I can do is add either BasicBritishInfantry or BasicLightArtillery. I tried cavalry, I tried machine guns none would place. It does not make sense, there must be an explanation for it. Thanks for any help trying to figure this out.
 
No, there has not to be a reason :D :crazyeye:.

I've also experienced that problem.
Tried to trigger something, including units, which gave me with the first unit a completly other unit, with the second unit no unit, but the third unit worked :crazyeye:.
 
Please tell us what civ version you are working with. Is it the latest, BTS 3.19?

Please confirm you have python exceptions turned on and you are looking for any errors in PythonErr.log.

If you are using 3.19, I am surprised anything is working since you have the wrong number of arguments in your calls to initUnit.
 
It's civ 4 vanilla v. 1.74. I have been working on this for awhile, I am almost done, and after I am going to start updating it to BTS 3.19 RevolutionsDCM.

No, there has not to be a reason :D :crazyeye:.

I've also experienced that problem.
Tried to trigger something, including units, which gave me with the first unit a completly other unit, with the second unit no unit, but the third unit worked :crazyeye:.

Well J, you would know so I stand corrected, it's still damn frustrating...lol. The events work, just won't give me a god damn machinegunner, those crumpet eatin' Brits are going to get shot to hell by the Germans without a few machine gun battalions. Tell me is Python more reliable with BTS 3.19? Or god help us is it worse?

What I am going to do is add some grenadier units, and a German Flamethrower. Give the BEF two MG battalions and leave the rest be. Download it, so people can start playtesting, and start working on the updated version.

What determines how the code looks for a unit? How does it find one unit type but cannot find another. I don't see how there is no explanation, if you want I can send you the whole code, maybe something in there is causing the problem.
 
I have not used the 1.xx versions, but I have written a lot of python with 3.17 and 3.19. I have never experienced random behavior from python. I have experienced programming errors I have made, which caused what seemed to be random behavior. But, that is different.

Can you confirm if you are using python logging, so you will see any exceptions? I apologize if this seems obvious, but many people post questions whose answers are easy to spot based on the exception text.
 
Simple explanation:

You have two functions both called Oct_1914.

When you define the second one, it replaces the first one. The second one delivers artillery. Thus, you only get artillery no matter how you modify the first one.
 
There are other things that could go wrong. Is all the art assigned to the correct units? Have you tried looking up the unit ID from the Python console?

  1. Hit ~ (tilde, hold SHIFT).
  2. iUnit = gc.getInfoTypeForString("")
  3. print gc.getUnitInfo(iUnit).getDescription()
Try adding logging output to your event:

Code:
pPlayer = gc.getPlayer(self.iBritainID)
			
iUnitType = self.iBritainBritishMachinegunID

[B][COLOR="Red"]CvUtil.PyPrint("machinegun = %d, %s" % (iUnitType, gc.getUnitInfo(iUnitType).getDescrption()))[/COLOR][/B]

iCityX = pPlayer.getCity(iCityID).getX()
iCityY = pPlayer.getCity(iCityID).getY()
 
Simple explanation:

You have two functions both called Oct_1914.

When you define the second one, it replaces the first one. The second one delivers artillery. Thus, you only get artillery no matter how you modify the first one.

For instance Oct_1914 and Oct2_1914. I will try that first. Thank you

I have not used the 1.xx versions, but I have written a lot of python with 3.17 and 3.19. I have never experienced random behavior from python. I have experienced programming errors I have made, which caused what seemed to be random behavior. But, that is different.

Can you confirm if you are using python logging, so you will see any exceptions? I apologize if this seems obvious, but many people post questions whose answers are easy to spot based on the exception text.

I have not at this looked at the logs. If renaming the function does not work, then that's my next step.

And then there's that. :goodjob: Rename one of the functions.
I will let you know what happens. Thanks for your help everyone. I will sure need it more when this mod gets updated.

Here is PythonErr log

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

  File "CvEventInterface", line 25, in onEvent

  File "CvEventManager", line 164, in handleEvent

  File "CvWWIEvents", line 1413, in onBeginGameTurn

  File "CvWWIEvents", line 106, in turnChecker

  File "CvWWIEvents", line 579, in Oct_1914

AttributeError: 'module' object has no attribute 'PyPrint'
ERR: Python function onEvent failed, module CvEventInterface
 
Odd. Is it pyPrint? I use my own logging functions. Open CvUtil.py to find the correct name.
 
Back
Top Bottom