Fixing some RevDCM stuff

phungus420

Deity
Joined
Mar 1, 2003
Messages
6,296
Been working on trying to get RevDCM working, and there are a couple issues left. The main two I'm working on now is trying to get a leader change working (if the human selects this option their leader is changed, but the AI takes over for a certain number of turns). In the latest build the functionality isn't working correctly as the AI doesn't take over. I have no idea when this broke, but it was a long time ago and the codebase has changed significantly, so it's not possible to revert and check (proably a couple 100 revisions or so including a major overhaul dealing with MP compatibility).

So I looked at the text for the leadership change, and searched up that text key in Python, and back tracked through the functions to where the revoltion is made in the aptly named function makeRevolutionDecision. The problem I'm having is that for the human, all I can gather from the code is that it constructs the Revolution decision popup; I can't figure out how the button that is pressed goes forward and fires the actual functionality of the revolution. Specifically looking at this section of code I see this:
Spoiler :
Code:
		elif( revType == 'leader' ) :

			# Load special data for this type
			iNewLeaderType = revData.dict['iNewLeaderType']
			if( 'newLeaderName' in revData.dict.keys() ) :
				newLeaderName = revData.dict['newLeaderName']
				if( self.LOG_DEBUG ) : CvUtil.pyPrint("  Revolt - Potential new leader: %s"%(newLeaderName))
			bIsElection = revData.dict['bIsElection']
			iBuyOffCost = revData.dict.get( 'iBuyOffCost', -1 )

			# Compute approval rating (formula from demographics info screen)
			if (pPlayer.calculateTotalCityHappiness() > 0) :
				iHappiness = int((1.0 * pPlayer.calculateTotalCityHappiness()) / (pPlayer.calculateTotalCityHappiness() + \
									pPlayer.calculateTotalCityUnhappiness()) * 100)
			else :
				iHappiness = 100

			# Adjusted approval rating based on num cities in revolt
			if( numRevCities > pPlayer.getNumCities()/2 ) :
				if( self.LOG_DEBUG ) : CvUtil.pyPrint("  Revolt - Approval rating (initially %d) adjusted due to %d of %d cities revolting"%(iHappiness,numRevCities,pPlayer.getNumCities()))
				iHappiness = int( iHappiness - 100*(numRevCities - pPlayer.getNumCities()/2)/(2.0*pPlayer.getNumCities()) )
				iHappiness = max([iHappiness,25])

			revData.dict['iHappiness'] = iHappiness

			revoltDict = RevData.revObjectGetVal( pPlayer, 'RevoltDict' )
			revoltDict[iRevoltIdx] = revData
			RevData.revObjectSetVal( pPlayer, 'RevoltDict', revoltDict )

			# Other potential factors:
			# Player rank

			if( numRevCities > pPlayer.getNumCities()/2 ) :
				iOdds = 50
				if( bPeaceful ) :
					iOdds -= 20
				else :
					if( pTeam.getAtWarCount(True) > 1 ) :
						iOdds += 10
				if( pPlayer.hasTrait(iAggressive) ) :
					iOdds -= 30
			elif( numRevCities < pPlayer.getNumCities()/4 ) :
				iOdds = 25
				if( bPeaceful ) :
					iOdds -= 20
				else :
					if( pTeam.getAtWarCount(True) > 1 ) :
						iOdds += 10
				if( pPlayer.hasTrait(iAggressive) ) :
					iOdds -= 20
			else :
				iOdds = 35
				if( bPeaceful ) :
					iOdds -= 30
				else :
					if( pTeam.getAtWarCount(True) > 1 ) :
						iOdds += 10
				if( pPlayer.hasTrait(iAggressive) ) :
					iOdds -= 20

			if( bIsElection ) :
				if( iHappiness > 55 ) :
					iOdds += 40
				elif( iHappiness < 40 ) :
					iOdds -= 30
				elif( iHappiness < 50 ) :
					iOdds -= 15
				else :
					iOdds += 10

			iOdds += self.RevOpt.getLeaderOdds()

			if( self.LOG_DEBUG ) : CvUtil.pyPrint("  Revolt - Odds are %d"%(iOdds))
			if( self.LOG_DEBUG ) : CvUtil.pyPrint("  Revolt - Adjusted approval rating is %d"%(iHappiness))

			if( self.isLocalHumanPlayer(pPlayer.getID()) ) :
				# Offer choice
				if( self.LOG_DEBUG ) : CvUtil.pyPrint("  Revolt - Offering human choice on leader change")

				# Additions by Caesium et al
				caesiumtR = CyUserProfile().getResolutionString(CyUserProfile().getResolution())
				caesiumtextResolution = caesiumtR.split('x')
				caesiumpasx = int(caesiumtextResolution[0])/10
				caesiumpasy = int(caesiumtextResolution[1])/10
				popup = PyPopup.PyPopup( RevDefs.revolutionPopup, contextType = EventContextTypes.EVENTCONTEXT_ALL, bDynamic = False)
				if( self.centerPopups ) : popup.setPosition(3*caesiumpasx,3*caesiumpasy)
				# End additions by Caesium et al
				if( bPeaceful ) :
					popup.setHeaderString( localText.getText("TXT_KEY_REV_TITLE_PEACEFUL",()) )
				else :
					popup.setHeaderString( localText.getText("TXT_KEY_REV_TITLE_VIOLENT",()) )
				if( iOdds >= 70 ) :
					bodStr += "\n\n" + localText.getText("TXT_KEY_REV_ADVISOR_ACCEPT",())
				elif( iOdds <= 30 ) :
					bodStr += "\n\n" + localText.getText("TXT_KEY_REV_ADVISOR_REJECT",())
				else :
					bodStr += "\n\n" + localText.getText("TXT_KEY_REV_ADVISOR_NEUTRAL",())
				if( bIsElection ) :
					bodStr += "  " + localText.getText("TXT_KEY_REV_ADVISOR_APPROVAL",()) + " %d."%(iHappiness)
					if( iHappiness < 40 ) :
						bodStr += "  " + localText.getText("TXT_KEY_REV_ADVISOR_ELEC_LOSE",())
				popup.setBodyString( bodStr )
				popup.addButton( localText.getText("TXT_KEY_REV_BUTTON_ACCEPT",()) )
				buttons = ('accept',)
				popup.addButton( localText.getText("TXT_KEY_REV_BUTTON_REJECT",()) )
				buttons += ('reject',)
				if( iBuyOffCost > 0 and iBuyOffCost <= pPlayer.getGold() ) :
					if( bIsElection ) :
						popup.addButton( localText.getText("TXT_KEY_REV_BUTTON_BUY_ELECTION",()) + ' %d'%(iBuyOffCost) )
						buttons += ('buyelection',)
					else :
						popup.addButton( localText.getText("TXT_KEY_REV_BUTTON_BUYOFF",()) + ' %d'%(iBuyOffCost) )
						buttons += ('buyoff',)
				if( not bPeaceful and not 'iJoinPlayer' in revData.dict.keys() and not bIsBarbRev and (pRevPlayer.getNumCities() == 0) and self.offerDefectToRevs ) :
					popup.addButton( localText.getText("TXT_KEY_REV_BUTTON_DEFECT",()) )
					buttons += ('defect',)

				popup.setUserData( (buttons, pPlayer.getID(), iRevoltIdx) )
				# Center camera on city
				CyCamera().JustLookAt( cityList[0].plot().getPoint() )
				popup.launch(bCreateOkButton = False)

			elif (not pPlayer.isHuman()) :
				# Make AI decision
				if( self.LOG_DEBUG ) : CvUtil.pyPrint("  Revolt - Making AI choice on leader change")

				if( game.getSorenRandNum(100,'Revolt: switch leader') < iOdds ) :
					self.processRevolution( pPlayer, iRevoltIdx, cityList, revType, bPeaceful, True )

				else:
					if( iBuyOffCost > 0 and iBuyOffCost <= pPlayer.getGold() ) :
						if( bPeaceful ) :
							base = .8
						else :
							base = .7
#-------------------------------------------------------------------------------------------------
# Lemmy101 RevolutionMP edit
#-------------------------------------------------------------------------------------------------		
						buyOdds = int( float(iOdds)/2.0 + 75.0*(1.0 - pow(base,float(pPlayer.getGold())/float(iBuyOffCost))) )
#-------------------------------------------------------------------------------------------------
# END Lemmy101 RevolutionMP edit
#-------------------------------------------------------------------------------------------------		
						if( self.LOG_DEBUG ) : CvUtil.pyPrint("  Revolt - AI buyoff iOdds are %d, with base %.1f, from cost %d and gold %d"%(buyOdds,base,iBuyOffCost,pPlayer.getGold()))
						if( buyOdds > game.getSorenRandNum( 100, 'Rev - AI buyoff decision' ) ) :
							if( self.LOG_DEBUG ) : CvUtil.pyPrint("  Revolt - AI buyingoff rebels")
							revData.dict['bDidBuyOff'] = True

							revoltDict = RevData.revObjectGetVal( pPlayer, 'RevoltDict' )
							revoltDict[iRevoltIdx] = revData
							RevData.revObjectSetVal( pPlayer, 'RevoltDict', revoltDict )

							self.processRevolution( pPlayer, iRevoltIdx, cityList, revType, bPeaceful, False )
							return

					self.processRevolution( pPlayer, iRevoltIdx, cityList, revType, bPeaceful, False )

Like I said I can see that a Revolution menu is built with the buttons, but how do I track it from there? I'd like to specifically go to what happens when the human presses the "accept" button. Anyone know where I can go from here?

For greater context, the location of the RevolutionDCM SVN can be found below, and I'm including the Revolution.py folder in case someone has a hunch and wants to check it out. As usual when posting in this forum I'm perfectly willing to do the footwork here, I just don't know what step to take next and am hoping someone around here is familiar with how Python pop ups work so I can track the code to where the actual implementation of this option is made.

RevDCM itself: https://revolutiondcm.svn.sourceforge.net/svnroot/revolutiondcm/Trunk/RevolutionDCM/
RevDCM source: https://revolutiondcm.svn.sourceforge.net/svnroot/revolutiondcm/Trunk/SourceCode/CvGameCoreDLL/
 
The loss of control is supposed to happen the turn after the popup; just in case you were expecting it to happen immediately.
Spoiler :
Code:
	def controlLostHandler( self, iPlayerID, netUserData, popupReturn ) :
		if self.isLocalHumanPlayer(iPlayerID) :	
			if( self.LOG_DEBUG ) : CvUtil.pyPrint("  Revolt - Handling local control lost popup")
			iPlayer = netUserData[0]
[COLOR="Green"]#-------------------------------------------------------------------------------------------------
# Lemmy101 RevolutionMP edit
#-------------------------------------------------------------------------------------------------	[/COLOR]	
			if(not self.isLocalHumanPlayer(iPlayer)):
				return
			iNumTurns = netUserData[1]
			iNewLeaderType = netUserData[2]
[COLOR="Green"]			# This is sometimes not being called. So I moved it into the pre-dialog bit.
			# This is ok tho since it now happens on [U]NEXT[/U] turn not when dialog is okayed.
			#CyMessageControl().sendModNetMessage(self.netControlLostPopupProtocol, iPlayer, iNumTurns, iNewLeaderType, 0)   
#-------------------------------------------------------------------------------------------------
# END Lemmy101 RevolutionMP edit
#-------------------------------------------------------------------------------------------------[/COLOR]


edit: search for "setAIAutoPlay", you'll notice a lot of that was taken out for the MP fix.
 
I don't understand how that setAIAutoplay command could ruin MP though, but it was important. I'm also not sure how esle to do it, (plus AIAutoplay works in MP, so it's strange). Do you have the ability to test MP? This comp wol't handle it.
 
There is actually a way to do it, lemmy figured it out, and it's how most of the MP code changes were made durring RevolutionMP development. But you have to run a virtual machine on your comp, and have two versions of Civ4 running. My comp just wol't be able to do that, I only have 1gig of RAM. The thread on it is here:

http://forums.civfanatics.com/showthread.php?t=357943

Anyway uncommenting this code
Code:
#-------------------------------------------------------------------------------------------------
# Lemmy101 RevolutionMP edit
#-------------------------------------------------------------------------------------------------		
			# had to remove. is this important?
			#game.setAIAutoPlay( iPlayerID, 1 ) # Releases this player turn to the AI, human player changed below so that human now will control rebels
#-------------------------------------------------------------------------------------------------
# END Lemmy101 RevolutionMP edit
#-------------------------------------------------------------------------------------------------

Gets the "defect and lead rebels" option working again at least. But I'm afraid since it's a Lemmy fix it'll break MP

I still haven't been able to track down where and how the "accept" leader change is actually applied, but I'll keep looking.
 
It's in controlLostNetworkHandler
Code:
#-------------------------------------------------------------------------------------------------
# Lemmy101 RevolutionMP edit
#-------------------------------------------------------------------------------------------------		

		#if (self.isLocalHumanPlayer(pPlayer.getID())):
		#	game.setAIAutoPlay( iNumTurns )
		#	SdToolKitCustom.sdObjectSetVal( "AIAutoPlay", game, "bCanCancelAuto", False )
			SdToolKitCustom.sdObjectSetVal( "AIAutoPlay", game, "bCanCancelAuto", False )
		RevInstances.AIAutoPlayInst.abdicateMultiCheckNoMessage(iPlayer, iNumTurns, False)
#-------------------------------------------------------------------------------------------------
# Lemmy101 RevolutionMP edit
#-------------------------------------------------------------------------------------------------
 
Top Bottom