[Python] isForceCivic/isForceCivicOption

jkp1187

Unindicted Co-Conspirator
Joined
Aug 29, 2004
Messages
2,496
Location
Pittsburgh, Pennsylvania
Hello, all. I need some help in understanding what the code below means.

Searching through CvPlayer.cpp, I see the following code from "canRevolution":

Code:
        for (iI = 0; iI < GC.getNumCivicOptionInfos(); ++iI)
        {
            if (GC.getGameINLINE().isForceCivicOption((CivicOptionTypes)iI))
            {
                if (!GC.getGameINLINE().isForceCivic(paeNewCivics[iI]))
                {
                    return false;
                }
            }

            if (getCivics((CivicOptionTypes)iI) != paeNewCivics[iI])
            {
                return true;
            }
        }
    }

    return false;

What I am attempting to do is write code for one of my random events that will check to see if a specific civic (say, CIVICOPTION_LEGAL/FREE_SPEECH,) is currently forced (by a UN vote, for instance). If a specific civic for the legal category is forced, return false, otherwise return true.

This code is a little daunting to me, as there are several things in here (like: "GC.getGameINLINE()", "iI", and "++iI") that I'd not seen before and did not see in the API. If someone could help me understand this better, I'd really appreciate it. The above code looks like it might be close to what I want to do, but I'm just unclear on what everything in it means.

Thanks!
 
This code is a little daunting to me, as there are several things in here (like: "GC.getGameINLINE()", "iI", and "++iI") that I'd not seen before and did not see in the API. If someone could help me understand this better, I'd really appreciate it. The above code looks like it might be close to what I want to do, but I'm just unclear on what everything in it means.

Thanks!

In that code 'iI' is an integer variable, in C++ it is common practice to prefix variable names with their type as a single letter. Some common examples would be f (float or floating point number), i (integer), b (boolean or true/false) and s (string). In C++ you can not use a variable of one type to supply data of another type without re-casting the type... man there has to be a better way to explain that. If you look in the code you will see times where a function is expressed as:

thisFunction(iNumber, sString, (int) fFloat);

In this example we are passing the integer (turncated number) of the floating point number fFloat. This is neccessary when the function expects certain data types, in the same example the definition of the function might be something like: thisFunction(int arg1, string arg2, int arg3); so it will only accept an integer for the third argument. In the code you posted, this part: (CivicOptionTypes)iI) is converting the integer iI to a CivicOptionType enum.

In python you don't have to cast the type of a variable so having a little reminder in the name isn't as important. Anyway, that's all the lowercase i, s, f and b you see means, nothing fancy :)

Edit: Sorry, missed one :) The ++iI is simply incimenting the value of iI by one before the loop cycle (iI++ would be after), very similar to the last argument in pythons for blah in range (min,max,inciment). Its really just another way of saying "iI = iI + 1" or "iI += 1" for the most part, if that helps.

As for the code... sorry it's too late for that, I'll try tomorrow.
 
Thanks, Seven05. That makes sense.

I did not see the "isForceCivic" in the API, so I'm starting to think that this particular command isn't exposed to Python, so I guess I can't use it? (That seems odd to me, since canRevolution references it, and yet canRevolution is exposed to Python. :confused: Then again, stranger things happen in life, and, indeed, in school....)

I tried playing around with canRevolution this morning. I may not have been using the right syntax, but all I could do was get it to answer "TRUE" when a civ could do a revolution to ANY other civic:

pPlayer.canRevolution(0)

But that isn't exactly what I want -- I want to be able to check if pPlayer can do a revolution to, for instance, POLICE_STATE (effectively, to check if, for instance, a GOVERNMENT civic has been forced by UN vote or otherwise). I am not sure of the appropriate syntax to use here, and all of my guesswork has been for nought (I was using getCivicInfos/getNumCivicInfos and getCivicOptionInfo/getNumCivicOptionInfos to get the appropriate value to use.)
 
It's pretty common to have a function that is exposed to python contain (or use) functions that aren't exposed to python so don't be suprised by that. Without looking at the full canRevolution() code I'll guess that the argument is the civic ID that you want to change, and then it looks to see if that civic is forced. I'm not sure though since I haven't messed with that part myself, but I'm guessing you need to pass the civic ID where you have the zero and you can get that using the getInfoTypeFromString function.
 
It's pretty common to have a function that is exposed to python contain (or use) functions that aren't exposed to python so don't be suprised by that. Without looking at the full canRevolution() code I'll guess that the argument is the civic ID that you want to change, and then it looks to see if that civic is forced. I'm not sure though since I haven't messed with that part myself, but I'm guessing you need to pass the civic ID where you have the zero and you can get that using the getInfoTypeFromString function.


See, that's what I figured, too. Problem is when I use a value that is anything other than "0", I get an error message. So if I put "0" in, or if I pull back the value for CIVICOPTION_GOVERNMENT (which is "0"), or if I put the value for CIVIC_DESPOTISM ("0"), I get the value of "true" for canRevolution. If I put the value for CIVIC_POLICE_STATE ("3"), I get the error.

This is what is says in the API:

Code:
bool canRevolution (CivicTypes paeNewCivics)
bool (int (CivicTypes*) paeNewCivics)

Alas, I am not skilled enough yet to translate this into the proper syntax to specify things. I assume "CivicTypes" refers to CIVICOPTIONTYPE, and "paeNewCivics" refers to the specific civic in that type, but I don't know how to script it in a format that Python will like.... I feel that if I could get past that point, things here (and elsewhere) will just go easier.
 
paeXXX normally means a list. In this case it means a number because someone decided to mutilate the function on the way to python. There is no way to test for a specific civic using this function in python. 0 (treated as null, or nothing) is the only accepted number and it means "test if we can switch any civic to something else".

isForceCivic is not exposed to python.

canDoCivics is exposed to python and will check if the civic is forced. It takes a CivicType as argument.
 
Thanks -- I just messed around with canDoCivics in the Python console and it looks like it'll work perfectly! I hadn't even seen that.

I wish the API were a little more user-friendly....it's so easy for a noob like myself to miss something in that thing. :(
 
Back
Top Bottom