Bug in CvEventManager.py file

TheLopez

Deity
Joined
Jan 16, 2006
Messages
2,525
Location
Oregon
The bug: When onUnitCreated and onUnitBuilt called for all players a unit is built or created.

After doing some digging I found that there might be other areas in the file that could be affected.

Check out this part of my log when I create a game, I added the extra print outs:
Code:
PY:Player 0's alive status set to: 1
PY:Player 1's alive status set to: 1
PY:Player 2's alive status set to: 1
PY:Player 3's alive status set to: 1
PY:Player 4's alive status set to: 1
PY:Player 5's alive status set to: 1
PY:Player 6's alive status set to: 1
PY:Player 7's alive status set to: 1
PY:Player 8's alive status set to: 1
PY:Player 9's alive status set to: 1
PY:Player 10's alive status set to: 1
PY:Player 18's alive status set to: 1
PY:onUnitCreated: Opus created: Settler unit id: 8192
PY:onUnitCreated: Opus created: Scout unit id: 16385
PY:onUnitCreated: Tokugawa created: Settler unit id: 8192
PY:onUnitCreated: Tokugawa created: Warrior unit id: 16385
PY:onUnitCreated: Cyrus created: Settler unit id: 8192
PY:onUnitCreated: Cyrus created: Scout unit id: 16385
PY:onUnitCreated: Montezuma created: Settler unit id: 8192
PY:onUnitCreated: Montezuma created: Scout unit id: 16385
PY:onUnitCreated: Bismarck created: Settler unit id: 8192
PY:onUnitCreated: Bismarck created: Scout unit id: 16385
PY:onUnitCreated: Isabella created: Settler unit id: 8192
PY:onUnitCreated: Isabella created: Warrior unit id: 16385
PY:onUnitCreated: Elizabeth created: Settler unit id: 8192
PY:onUnitCreated: Elizabeth created: Warrior unit id: 16385
PY:onUnitCreated: Julius Caesar created: Settler unit id: 8192
PY:onUnitCreated: Julius Caesar created: Warrior unit id: 16385
PY:onUnitCreated: Roosevelt created: Settler unit id: 8192
PY:onUnitCreated: Roosevelt created: Warrior unit id: 16385
PY:onUnitCreated: Huayna Capac created: Settler unit id: 8192
PY:onUnitCreated: Huayna Capac created: Quechua unit id: 16385
PY:onUnitCreated: Asoka created: Settler unit id: 8192
PY:onUnitCreated: Asoka created: Warrior unit id: 16385

Checkout this part of the log after one turn:
Code:
PY:Started player: Opus upkeep
PY:onUnitCreated: Opus created: Warrior unit id: 24576
PY:onUnitBuilt: Opus built: Warrior unit id: 24576
PY:Ended player: Opus upkeep
PY:Started player: Tokugawa upkeep
PY:onUnitCreated: Tokugawa created: Warrior unit id: 24576
PY:onUnitBuilt: Tokugawa built: Warrior unit id: 24576
PY:Ended player: Tokugawa upkeep
PY:Started player: Cyrus upkeep
PY:onUnitCreated: Cyrus created: Warrior unit id: 24576
PY:onUnitBuilt: Cyrus built: Warrior unit id: 24576
PY:Ended player: Cyrus upkeep
PY:Started player: Montezuma upkeep
PY:onUnitCreated: Montezuma created: Warrior unit id: 24576
PY:onUnitBuilt: Montezuma built: Warrior unit id: 24576
PY:Ended player: Montezuma upkeep
PY:Started player: Bismarck upkeep
PY:onUnitCreated: Bismarck created: Warrior unit id: 24576
PY:onUnitBuilt: Bismarck built: Warrior unit id: 24576
PY:Ended player: Bismarck upkeep
PY:Started player: Isabella upkeep
PY:onUnitCreated: Isabella created: Warrior unit id: 24576
PY:onUnitBuilt: Isabella built: Warrior unit id: 24576
PY:Ended player: Isabella upkeep
PY:Started player: Elizabeth upkeep
PY:onUnitCreated: Elizabeth created: Warrior unit id: 24576
PY:onUnitBuilt: Elizabeth built: Warrior unit id: 24576
PY:Ended player: Elizabeth upkeep
PY:Started player: Julius Caesar upkeep
PY:onUnitCreated: Julius Caesar created: Warrior unit id: 24576
PY:onUnitBuilt: Julius Caesar built: Warrior unit id: 24576
PY:Ended player: Julius Caesar upkeep
PY:Started player: Roosevelt upkeep
PY:onUnitCreated: Roosevelt created: Warrior unit id: 24576
PY:onUnitBuilt: Roosevelt built: Warrior unit id: 24576
PY:Ended player: Roosevelt upkeep
PY:Started player: Huayna Capac upkeep
PY:onUnitCreated: Huayna Capac created: Quechua unit id: 24576
PY:onUnitBuilt: Huayna Capac built: Quechua unit id: 24576
PY:Ended player: Huayna Capac upkeep
PY:Started player: Asoka upkeep
PY:onUnitCreated: Asoka created: Warrior unit id: 24576
PY:onUnitBuilt: Asoka built: Warrior unit id: 24576
PY:Ended player: Asoka upkeep
PY:Started player: Barbarian upkeep
PY:Ended player: Barbarian upkeep

Root-cause:
Most of the methods in the CvEventManager.py file do not return a 0 or a 1 as expected causing events such as the onUnitCreated and onUnitBuilt in my example to flow from one player to another since it is never consumed. After having all of the unit related event handlers return a 0 the problem disappeared, please note this was just to prove that it was indeed a possible solution. Here is part of my log after I updated the CvEventManager.py file (note that the unit IDs are no longer repeated through each player's turn:
Code:
PY:Started player: Opus upkeep
PY:onUnitCreated: Opus created: Scout unit id: 106496
PY:onUnitBuilt: Opus built: Scout unit id: 106496
PY:Ended player: Opus upkeep
PY:Started player: Montezuma upkeep
PY:onUnitCreated: Montezuma created: Settler unit id: 90121
PY:onUnitBuilt: Montezuma built: Settler unit id: 90121
PY:Ended player: Montezuma upkeep
PY:Started player: Roosevelt upkeep
PY:onUnitCreated: Roosevelt created: Settler unit id: 73735
PY:onUnitBuilt: Roosevelt built: Settler unit id: 73735
PY:Ended player: Roosevelt upkeep
PY:Started player: Huayna Capac upkeep
PY:onUnitCreated: Huayna Capac created: Settler unit id: 90121
PY:onUnitBuilt: Huayna Capac built: Settler unit id: 90121
PY:Ended player: Huayna Capac upkeep
PY:Started player: Julius Caesar upkeep
PY:Ended player: Julius Caesar upkeep
PY:Started player: Napoleon upkeep
PY:onUnitCreated: Napoleon created: Settler unit id: 73735
PY:onUnitBuilt: Napoleon built: Settler unit id: 73735
PY:Ended player: Napoleon upkeep
PY:Started player: Alexander upkeep
PY:onUnitCreated: Alexander created: Work Boat unit id: 106505
PY:onUnitBuilt: Alexander built: Work Boat unit id: 106505
PY:Ended player: Alexander upkeep
PY:Started player: Saladin upkeep
PY:Ended player: Saladin upkeep
PY:Started player: Bismarck upkeep
PY:onUnitCreated: Bismarck created: Settler unit id: 98311
PY:onUnitBuilt: Bismarck built: Settler unit id: 98311
PY:Ended player: Bismarck upkeep
PY:Started player: Tokugawa upkeep
PY:onUnitCreated: Tokugawa created: Settler unit id: 90119
PY:onUnitBuilt: Tokugawa built: Settler unit id: 90119
PY:Ended player: Tokugawa upkeep
PY:Started player: Isabella upkeep
PY:onUnitCreated: Isabella created: Settler unit id: 98309
PY:onUnitBuilt: Isabella built: Settler unit id: 98309
PY:Ended player: Isabella upkeep
PY:Started player: Barbarian upkeep
PY:Ended player: Barbarian upkeep
iTurn: 12

The solution:
There are four possible solutions

1) Do nothing. This is the worst of the solutions since nothing will change and mod makers might be fighting bugs thinking it's in their code

2) Change the CvEventManager.py file. This would fix the issue but it doesn't guarantee that everyone will replace their own copies of the file. One option is for all mod makers to include the updated version in their mods.

3) Mod makers make sure that their overloaded methods return the correct value. Again this would fix the issue but it doesn't address the cases where mod makers forget to return the correct values.

4) In the short term do option 3 and in the long term request that FireAxis fix the CvEventManager.py in their next fix. This way everyone who applies the next patch gets the fix.


So what do people think?

While were on the topic of the CvEventManager.py file, could we also ask that FireAxis fix the onChangeWar method so it actually works :D.
 
Hmmm. In my version of the event manager the unit events seem to be returning fine (from looking at the code)
Code:
	def onUnitCreated(self, argsList):
		'Unit Completed'
		unit = argsList[0]
		player = PyPlayer(unit.getOwner())
		if (not self.__LOG_UNITBUILD):
			return
As long as self.__LOG_UNITBUILD is 0 (default) then it should work shouldn't it?
 
The Great Apple said:
Hmmm. In my version of the event manager the unit events seem to be returning fine (from looking at the code)
Code:
	def onUnitCreated(self, argsList):
		'Unit Completed'
		unit = argsList[0]
		player = PyPlayer(unit.getOwner())
		if (not self.__LOG_UNITBUILD):
			return
As long as self.__LOG_UNITBUILD is 0 (default) then it should work shouldn't it?
nope, it doesn't, just look at the clips from my logs, if the event handlers worked correctly then the unit IDs should be different for each unit being created right?

Here are my onBeginPlayerTurn, onEndPlayerTurn, onUnitCreated and onUnitBuilt methods, just change yours and then look at your log.

Code:
	def onBeginPlayerTurn(self, argsList):
		'Called at the beginning of a players turn'
		iGameTurn, iPlayer = argsList
		CvUtil.pyPrint("Beginning of " + gc.getPlayer(iPlayer).getName() + " turn upkeep")

	def onEndPlayerTurn(self, argsList):
		'Called at the end of a players turn'
		iGameTurn, iPlayer = argsList

		
		if (gc.getGame().getElapsedGameTurns() == 1):
			if (gc.getPlayer(iPlayer).isHuman()):
				if (gc.getPlayer(iPlayer).canRevolution(0)):
					popupInfo = CyPopupInfo()
					popupInfo.setButtonPopupType(ButtonPopupTypes.BUTTONPOPUP_CHANGECIVIC)
					popupInfo.addPopup(iPlayer)
		
		CvAdvisorUtils.resetAdvisorNags()
		CvAdvisorUtils.endTurnFeats(iPlayer)
		CvUtil.pyPrint("End of " + gc.getPlayer(iPlayer).getName() + " turn upkeep")


	def onUnitCreated(self, argsList):
		'Unit Completed'
		unit = argsList[0]
		player = PyPlayer(unit.getOwner())

		CvUtil.pyPrint("onUnitCreated: " + player.getName() + " created: " + unit.getName() + " unit id: " + str(unit.getID()))		
		if (not self.__LOG_UNITBUILD):
			return 


	def onUnitBuilt(self, argsList):
		'Unit Completed'
		city = argsList[0]
		unit = argsList[1]
		player = PyPlayer(city.getOwner())

		CvAdvisorUtils.unitBuiltFeats(city, unit)
		CvUtil.pyPrint("onUnitBuilt: " + player.getName() + " built: " + unit.getName() + " unit id: " + str(unit.getID()))		
		if (not self.__LOG_UNITBUILD):
			return 
		CvUtil.pyPrint('%s was finished by Player %d Civilization %s' 
			%(PyInfo.UnitInfo(unit.getUnitType()).getDescription(), player.getID(), player.getCivilizationName()))
 
What do those functions look like after you make the fix?
 
Basically I propose that they should either return a 0 or a 1, depending on the method.
 
If you're basing this on the fact that you've seen Unit IDs which are the same - they are based on the player so different players can (and will) have units with the same ID #s. If you're noticing something besides that let me know.
 
Trip said:
If you're basing this on the fact that you've seen Unit IDs which are the same - they are based on the player so different players can (and will) have units with the same ID #s. If you're noticing something besides that let me know.
Curses... and I thought they were unique to each unit. Surely there isn't much point in having an ID if it isn't unique?

*mutters something rude under his breath*

Thanks for setting us right anyway!
 
Actually when I started returning either 1's or 0's in the different unit event handlers I stopped getting the event information printed for every player every turn, yes I agree that there is still some duplication of unit ID's because unit IDs are unique per player.

Look at the contents of the 2nd and 3rd log contents, the 2nd one is without the event handlers returning anything, the 3rd is when they are returning either a 1 or 0. Drastically different contents.
 
Back
Top Bottom