Iterate buildings

Baldyr

"Hit It"
Joined
Dec 5, 2009
Messages
5,530
Location
Sweden
I need to check whether or not any building in a given city belong to a certain BuildingClassType. Because there seems to be no CyBuilding class and therefore no CyCity.getBuilding() method. Even though there is a CyCity.getNumBuildings() there is now way to iterate though them. And while there is a CyCity.getNumBuilding() method there is no CyCity.getNumBuildingClass() method. :p

It seems that I basically have to go:
Code:
def checkBuildingClass(pCity, eBuildingClass):
    for building in range(gc.getNumBuildingInfos()):
        if pCity.isHasBuilding(building):
            if gc.getBuildingInfo(building).getBuildingClass() == eBuildingClass:
                return True
Is this really necessary or is there perhaps a better way of doing this? :confused:

Sure, I could do it this way also:
Code:
def checkBuildingClass(pCity, eBuildingClass):
    for building in getBuildings(pCity):
        if getBuildingClass(building)  == eBuildingClass:
            return True

def getBuildings(pCity):
    lBuildingsList = []
    for building in range (gc.getNumBuildingInfos()):
        if pCity.isHasBuilding(building):
            lBuildingsList.append(building)
    return lBuildingsList

def getBuildingClass(eBuilding):
    return gc.getBuildingInfo(eBuilding).getBuildingClass()
Thats basically just the same thing, but even worse as I would iterate through every single building type - every time. There ought to be something in the Python API to keep this iteration business to a minimum. :p (I don't currently know how to do this in C++ to make it faster. But perhaps it takes no measurable time at all to check 150 some items through CvInfoBase?)

There could at least be a CvBuildingClassInfo.getBuildingTypes(). Perhaps I could just build a dictionary of all building classes and their associated building types at initialization? Then I could fetch the values I need from there.
Code:
global buildingClassIndex
buildingClassIndex = {}
for building in range(gc.getNumBuildingInfos()):
    eBuildingClass = gc.getBuildingInfo(building).getBuildingClass()
    buildingClassIndex[eBuildingClass] = buildingClassIndex.get(eBuildingClass, []).append(building)
And finally add this:
Code:
def getClassBuildings(eBuildingClass):
    return buildingClassIndex[eBuildingClass]
Did I just solve my own problem? (It took a hour or so to write this post... :rolleyes:)
 
If the normal rule that a city owned by player X can only have the buildings buildable by that player's civilization type, you can determine the single building type from a single building class using the CvCivilizationInfo class.

Code:
# given a pCity
pOwner = gc.getPlayer(pCity.getOwner())
pCivilization = gc.getCivilizationInfo(pOwner.getCivilizationType())
eBuilding = pCivilization.getCivilizationBuildings(eBuildingClass)
if pCity.getNumBuildings(eBuilding) > 0:
    # has the building class

Note: I haven't checked the names of these functions in a while, but the logic is sound.

If you need this to work in a mod where a player can building UUs of other civilizations, you are left with looping through all buildings or creating a dictionary that maps each building class to a list of the buildings that are of that class.
 
If the normal rule that a city owned by player X can only have the buildings buildable by that player's civilization type, you can determine the single building type from a single building class using the CvCivilizationInfo class.
This would probably be very helpful.. :king:
 
Hey, i was seaching in the dll files and couldn't find this :
CvCity.getNumBuildings(); function... I know cuz I was needing exatly that ...
There is a function similar with CvPlayer ... But no with the city itself...
Expecially exposed to python ...
No way, without writing functions, to se the number of unique buildings, or building class in one specific city.

But I may be not right ...
 
I just found out that there is a AdjustBuilding() function in the CvUtil module. I'm not sure how it works though, especially as the CyCity.setNumRealBuildingIdx() method isn't covered in the API.
 
Hey, i was seaching in the dll files and couldn't find this :
CvCity.getNumBuildings(); function... I know cuz I was needing exatly that ...
There is a function similar with CvPlayer ... But no with the city itself...
Expecially exposed to python ...
No way, without writing functions, to se the number of unique buildings, or building class in one specific city.

But I may be not right ...

You must be looking in the wrong place. Try the BtS SDK instead of an earlier version (the one in the BtS folder, not the one in the main Civ folder or Warlords).

Line 4815 of CvCity.cpp is the definition of CvCity::getNumBuilding(BuildingTypes eIndex).
This is in BtS. I think all of this type of thing was added in BtS since in earlier versions you could only have one of any specific building in a city (this may have been added specifically for Final Frontier, which allows up to 7 since each planet in a star system can have one of most buildings and some star systems have 7 planets).

In earlier versions it only had CvCity::isHasBuilding(), which no longer exists in BtS (but does exist in the Python interface, apparently).

Edit: for creating buildings in Python, BtS has setNumRealBuilding. Apparently you can only create real buildings, not free buildings, in Python (which makes sense - free buildings are those created by other buildings, like the free monuments from stonehenge). The SDK also has setNumFreeBuilding (and a setNumRealBuildingTimed - whatever that is) but these are not listed in the Python SDK docs and are therefore probably not exposed to Python.
 
Ahh nice.. ! I ll check again, I probably messed up =p

Yes the "isHasBuilding" stuff still exists...

At least in some mods I saw with python ...

Thanks!
 
Vanilla (and Warlords?) only allowed one of each type of building per city. BTS allows you to have two Monuments, for example, so the function was changed to getNumBuilding instead of isHasBuilding.
 
Ahh I see ... Is because I just have been told about the "<bnolimit>" tag in the building class... but I haven't actually had seached for that, ok so is a much better way to handle with that ...

I have a lot more questions in the way my planning mod get form, however I'm forever stucked in the compiling SDK process. I keep getting errors, keeping seaching for then here and in the internet in general wih no success. It's very disapointing ...

I'm using a AMD Athlon 64 x2, using the http://modiki.civfanatics.com/index.php/How_to_Install_the_SDK tutorial in all forms,
tried a couple differente Makefiles... nothing ... Tryed to compile from "Ide-Cdm" from VS8 no response, from directly cdm nothing, from the direct toolkit cdm nothing same errors... Uninstalled all the 64bits files I found nothing too, tried all the 32 bits aproches I could find nothing too ...I've posted this in other topic so I won't redigit if.. But I'm open to show all diferente errors in diferent aprochs ... I'm sure I can became a great contributor to the modding network, but sometimes getting stucked without even begining make you less promp to start the real work

By the way, I'm working in this modding world for 2 reasons 1 because I really like the idea of the game, although part by part I want to make it a tottaly diferent shape ( may be even a new (open-souce ? ) game) , and the second "more real" for my atual situation for keep learning C language , and practicing python at least at this basic level I know that the SDK is not in C but C++ but helps too ...

Thanks if someone read this post, sorry for the time, hope to get some clues from here ...
 
Top Bottom