Help with Python

RenaissanceFan

Warlord
Joined
Mar 15, 2011
Messages
125
Hello again. I got the backbone for one of my mods almost done, but I'm having trouble to make it work. Please tell me what am I doing wrong. Two things:

1) I created a button at the Domestic Advisor for calling a popup, but the handleInput function doesn't seem to be working:

- Button declaration:
Code:
		screen.setImageButton( "CreateProvince", "", self.nScreenWidth - 165, self.nScreenHeight - 45, 28, 28, WidgetTypes.WIDGET_ACTION, -1, -1 )
		screen.setStyle( "CreateProvince", "Button_HUDLog_Style" )

- handleInput part of code:
Code:
                if (inputClass.getFunctionName() == "CreateProvince"):
                        if (inputClass.getNotifyCode() == NotifyCode.NOTIFY_CLICKED):
                                pPlayer = gc.getActivePlayer()
                        
                                CityChoice = CyPopupInfo()
                                CityChoice.setButtonPopupType(ButtonPopupTypes.BUTTONPOPUP_PYTHON)
                                CityChoice.setText("Choose your new province's capital:")
                                CityChoice.setOnClickedPythonCallback("makeProvince")
                                (pLoopCity, iter) = pPlayer.firstCity(false)
                                while(pLoopCity):
                                        if (pLoopCity.isCapital() != True):
                                                CityChoice.addPythonButton(pLoopCity.getName())
                                        i += 1
                                        (pLoopCity, iter) = player.nextCity(iter, false)
                                CityChoice.addPopup(pPlayer)

2) Here's the function that the popup calls. Also, where should I place it?
Code:
        def makeProvince (self, argsList):
                ButtonID = argsList[0]
                pPlayer = gc.getActivePlayer()
                tPlayer = gc.getActivePlayer().getTeam()
                
                for i in range(0, gc.getMAX_CIV_PLAYERS()) :
			if( not gc.getPlayer(i).isEverAlive() and not gc.getPlayer(i).isAlive() ) :
				newPlayerId = i
				break
		game.addPlayer(i, gc.getInfoTypeForString("LEADER_GOVERNOR", gc.getInfoTypeForString("CIVILIZATION_PROVINCE"))
                iVassal = gc.getPlayer(i)
                tVassal = gc.getPlayer(iVassal).getTeam()
                               
                gc.getPlayer(iVassal).acquireCity(pPlayer.getCity(ButtonID+1), False, True)
			for iTech in range(gc.getNumTechInfos()):
				if (tPlayer.isHasTech(iTech)):
					iVassal.setHasTech(iTech, True, iVassal, False, False)
		pPlayer.assignVassal(gc.getPlayer(iVassal).getTeam(), True)
 
If your Python really looks like that, with no indentation, then that would be the problem (well, the first problem, there could be more) for any "it doesn't work" type issue.
 
Seeing that you're using the
Code:
 tags this is indeed an issue of indentation. Indentation isn't used to make the code readable, but instead defines the [I]flow [/I]of the code. You basically divide the lines of code into various [I]blocks [/I]of code. Look into some basic Python programming on this.
[spoiler]An easy way to knowing when there needs to be a new indentation level is when any line of code ends with a colon. But you still need to understand when to get [I]back [/I]to a previous level of indentation.[/spoiler]
 
It's not an indentation problem, I just erased it here. I'm already re-indenting it. The fact is, there's some error that's not loading the interface.
 
Its not "some" error. Its probably a very specific Python exception and if you would just post whatever it is, it would enable us to help you with the problem at hand.
Spoiler :
Look in \Documents\Games\Beyond the Sword\Logs\PythonErr.log

I did notice one odd indentation related issue just glancing the re-edited code above:
Code:
			for iTech in range(gc.getNumTechInfos()):
Because the previous line doesn't end with a colon, there can not be yet another level of indentation. Note that the code has to make sense, and this does not.
 
You should enable the python exceptions, so that you better notice the errors.
In you main .ini file (Documents\My Games\BtS), change this value:
PHP:
; Set to 1 for no python exception popups
HidePythonExceptions = 1

to 0 please.
 
Part 1 first. I did what The_J said, and got the following bug:

Spoiler :
Traceback (most recent call last):

File "CvScreensInterface", line 657, in handleInput

File "CvDomesticAdvisor", line 400, in handleInput

ArgumentError: Python argument types in
CyPopupInfo.addPopup(CyPopupInfo,CyPlayer)
did not match C++ signature:
addPopup(class CyPopupInfo {lvalue}, int)


As for part 2, there seems to be a dozen errors. Here's the file, take a look yourselves. Only python file in mod.
 

Attachments

  • CvDomesticAdvisor.zip
    4.9 KB · Views: 51
As for the exception you posted, it simply states that you shouldn't use a CyPlayer instance but rather a integer value as the parameter, in this case the PlayerType or PlayerID. What you do is you change this line:
Code:
CityChoice.addPopup(pPlayer)
to:
Code:
CityChoice.addPopup(pPlayer[COLOR="Red"].getID()[/COLOR])
I don't have the time to download, install and debug your entire module, but you should at least try to sort this out yourself. Because chances are that nobody else has that sort of time either.

Note that its critical that you use the CivIV Python API when doing Python modding. Because it tells you what parameters should go into what method. (Link in my signature.)
 
Well, I tinkered with the code a lot, but with almost all changes it gave this error:

Spoiler :
File "CvDomesticAdvisor", line 398, in handleInput

TypeError:
this constructor takes no arguments


Line 398 is "CityChoice.addPythonButton(pLoopCity.getName())".
 
Top Bottom