Python building XML read

Pla5ma

Chieftain
Joined
Apr 30, 2008
Messages
20
How can I read from CIV4buildinginfos data of XML tag?
There is getXMLdata but it wont work for me...
 
Exactly, grab the CvBuildingInfo that you want using gc.getInfoTypeForString(<key>) to find its ID and then gc.getBuildingInfo(id) to get the object. With that, you can inspect all the information that's in the XML.

Code:
eType = gc.getInfoTypeForString("BUILDING_COTHON")
info = gc.getBuildingInfo(eType)
if info.getCoastalTradeRoutes() > 0:
   ...
 
If, however, you are reading a Python tutorial (general, not modding for Civ), and are attempting to use native capability to directly read XML data, then things are more complicated, and the game isn't completely set up to want to allow such things. You can probably pull it off just fine, but there will be a LOT of legwork to set up a proper python environment, file interfaces and whatnot, and then a significant performance hit while running the game.

Civ is built so that XML is read by the DLL when you first launch the program, then never touched again. Python asks for data from the DLL, and cannot directly access the XML information at any point. New fields added to the XML needs to be set up in the DLL to work.
 
What I want is to get prereqs for buildings without looping trough all information.
I know getPrereqNumOfBuildingClass but i dont know how to use it right.

Python is so strange compared to compiler languages. :)
 
Most of the data structures are set up to require looping. Just bite the bullet, it's not so bad. Looping over 50 building classes is trivial, even in an interpreted language like Python.

I don't have time to look at the SDK to make sure the getPrereqNumOfBuildingClass() function works like I think it does, but if I'm right you use it like this:

Code:
info = gc.getBuildingInfo(...)
for iClass in range(gc.getNumBuildingClassInfos()):
    if info.getPrereqNumOfBuildingClass(iClass) > 0:
        # requires at least one of building class iClass
        ...

The function will return the number of buildings of the class iClass that are required to build the building described by "info".
 
For speed's sake, you should store the number of buildings in a local variable, then loop over the local variable. Otherwise you are calling the DLL and asking how many buildings there are each time you finish checking one of the buildings.
 
I'm not intimately familiar with Python's internals, but I don't believe this is true. The range(N) function creates a list of all the values from 0 to N - 1. The for construct then iterates over that list. Thus, the DLL is called only once to find N.

However, I often do store the total # of buildings, units, techs, etc. if I'm going to use them more than once. It cannot change without loading/unloading a mod, and the Python subsystem is reinitialized in that case, so these are safe to store.
 
Yeah, the SDK code itself is really bad about calling the same function over and over instead of storing the result in a local variable. On rare occasions it will declare a CvBuildingInfo& (reference) to use locally, but far more often you'll see several calls to GC.getBuildingInfo(eBuilding), every time it needs a value about the same building.

I seriously doubt this is a huge drain on processor time, but to me it's even more a matter of making the code more difficult to read since you need to check each call to make sure it's using the same building # as it did before. For the life of me I have not been able to think of a reason for doing it this way consciously, like ease of use or understanding or readability. Sometimes it's worthwhile to forsake speed for those, but in this case you lose them all. :confused:
 
Top Bottom