Passing python list to C++

jdog5000

Revolutionary
Joined
Nov 25, 2003
Messages
2,601
Location
California
I'm trying to invoke the following CyPlayer function from Python, but running into issues:

void CyPlayer::revolution(int /*CivicTypes**/ paeNewCivics, bool bForce)

Where paeNewCivics is expected to be an array of number of civic options (govt, legal, etc) ... what can I pass to this function?

If I was writing the C++ side, I know how to accept a Python list as an arg (see here) but I can't figure out how to use the existing SDK function. When I pass a list, it errors saying it was expecting an int type for that arg. Ideas?

Thanks in advance.
 
JDog, I understood everything you said right up until "I am trying to invoke...." :mischief: :p . Seriously though, I would like to keep track of this thread, as I may learn a thing or to about C++
Oh and, btw, I LOVE your Barb/Revolution mod.

Aussie_Lurker
 
jdog5000 said:
I'm trying to invoke the following CyPlayer function from Python, but running into issues:

void CyPlayer::revolution(int /*CivicTypes**/ paeNewCivics, bool bForce)

Where paeNewCivics is expected to be an array of number of civic options (govt, legal, etc) ... what can I pass to this function?

If I was writing the C++ side, I know how to accept a Python list as an arg (see here) but I can't figure out how to use the existing SDK function. When I pass a list, it errors saying it was expecting an int type for that arg. Ideas?

Thanks in advance.

Not sure why they exposed it to python, since I don't see it used, nor would I see it being able to be used. Especially with the problems it would probably cause people with MP issues (using it in a context such as the CvCivicsScreen would cause OOS errors, since most of the code is only called on the local computer that's viewing the screen).

Luckily, there's another function specifically for this purpose. What they use instead in CvCivicsScreen.py is this:

Code:
if (activePlayer.canRevolution(0)):
	messageControl = CyMessageControl()
	messageControl.sendUpdateCivics(self.m_paeDisplayCivics)

Most likely, sendUpdateCivics takes in as arguments a python list, which it converts into an integer array. Then, it uses that integer array for the call to CvPlayer::revolution().

Note that there is no player argument. I'm assuming that this is because the call is assumed to refer to the active player. Thus, it's important to make sure you have some sort of guard to be sure that the area where it's being called from in python is only going to be run on the active computer. The sendUpdateCivics function will pass the message along to other players in the game without you needing to, both on the local computer and over the network to other players in the MP game.
 
Gerikes said:
Not sure why they exposed it to python, since I don't see it used, nor would I see it being able to be used. Especially with the problems it would probably cause people with MP issues (using it in a context such as the CvCivicsScreen would cause OOS errors, since most of the code is only called on the local computer that's viewing the screen).
Hmm ... my goal was to use it in my Revolution mod, where if you were running a Theocracy, citizens in a Holy city for a non-state religion might demand that you end your Theocracy or they'll fight you. So, the plan was not to even show the civics screen ... a different popup gives you the options of switch or not.

There is another way to go fortunately, using CvPlayer::setCivics and changeAnarchyTurns ... I just figured you ought to be able to use the functions they supplied?

Gerikes said:
Code:
if (activePlayer.canRevolution(0)):
	messageControl = CyMessageControl()
	messageControl.sendUpdateCivics(self.m_paeDisplayCivics)

Most likely, sendUpdateCivics takes in as arguments a python list, which it converts into an integer array. Then, it uses that integer array for the call to CvPlayer::revolution().

Note that there is no player argument. I'm assuming that this is because the call is assumed to refer to the active player. Thus, it's important to make sure you have some sort of guard to be sure that the area where it's being called from in python is only going to be run on the active computer. The sendUpdateCivics function will pass the message along to other players in the game without you needing to, both on the local computer and over the network to other players in the MP game.
The setCivics function does some updating I believe so hopefully this won't be an issue ... I have to admit I don't quite understand how multiplayer works in terms of what's computed where, so I am in the dark as to whether my mod is multiplayer friendly or not ...
 
Aussie_Lurker said:
JDog, I understood everything you said right up until "I am trying to invoke...." :mischief: :p . Seriously though, I would like to keep track of this thread, as I may learn a thing or to about C++
Oh and, btw, I LOVE your Barb/Revolution mod.

Aussie_Lurker
Thanks :)
J
 
jdog5000 said:
Hmm ... my goal was to use it in my Revolution mod, where if you were running a Theocracy, citizens in a Holy city for a non-state religion might demand that you end your Theocracy or they'll fight you. So, the plan was not to even show the civics screen ... a different popup gives you the options of switch or not.

I assumed so, but was just pointing out an example of how it's done there (assuming Firaxis knows how to use it's own code :P)

There is another way to go fortunately, using CvPlayer::setCivics and changeAnarchyTurns ... I just figured you ought to be able to use the functions they supplied?

That would work too, but...

The setCivics function does some updating I believe so hopefully this won't be an issue ... I have to admit I don't quite understand how multiplayer works in terms of what's computed where, so I am in the dark as to whether my mod is multiplayer friendly or not ...

Both setCivics and changeAnarchyTurns just do exactly what they say, but they won't pass the message along to other computers in the game about what's going on if it is the case that the code is currently being run only on the local computer (which is normally the case in popups and screens).

You might want to try this if you're not completely sure if the code you're writing will be run on just one computer or for sure on all of them, where pPlayerId is the player whose civics you wish to change:

Code:
if ( pPlayerId == gc.getGame().getActivePlayer() ):
	CyMessageControl().sendUpdateCivics(self.m_paeDisplayCivics)

This way, if your code is only being run on one computer, it will work like normal, and if it's being run on any other computers they won't do the call, but get the message when sendUpdateCivics sends it across the network to them.

Edit: On second thought, I'm not exactly sure how this would work on some of the other multiplayer modes like hotseat, pbem and pitboss. I still have some testing that I want to do.

And I don't know, but I'm willing to bet that using sendUpdateCivics will also change the anarchy turns for you, since nowhere in CvCivicsScreen.py does it change the anarchy turns.
 
Back
Top Bottom