basic python question reg. types and classtypes

Ploeperpengel

academic precarity
Joined
Feb 2, 2006
Messages
4,748
Location
Berlin
I found it simple to get a class of a certain type:
Code:
iBuildingClassType = gc.getBuildingInfo(iBuildingType).getBuildingClassType()
in onBuldingBuild seems to work however the other way round if I want to get the buildingID of an existant buildingClass in a city doesn't seem to work the same way:

Code:
		#Citydefense upgrades			
		iCitydefense3 = gc.getInfoTypeForString('BUILDINGCLASS_HIGHWALLS')	
		iCitydefense2 = gc.getInfoTypeForString('BUILDINGCLASS_CITY_WALLS')	
		iCitydefense1 = gc.getInfoTypeForString('BUILDINGCLASS_WALLS')		
		if iBuildingClassType == iCitydefense3:
			iRazeBuilding = pCity.getBuildingClassType(iCitydefense2).getBuildingType() 
			pCity.setNumRealBuilding(iRazeBuilding), 0)
		if iBuildingClassType == iCitydefense2:
			iRazeBuilding = pCity.getBuildingClassType(iCitydefense1).getBuildingType() 
			pCity.setNumRealBuilding(iRazeBuilding), 0)

returns an error for pCity.setNumRealBuilding(iRazeBuilding), 0). What am I doing wrong?
 
to explain further the goal. I have three tiers for walls in this example. Once the second tier wall is build the first tier should be deleted. I need to find a certain building of a buildingclass because the actual buildingtypes might change depending on which civ is the actual player(other civs might get Palisades or Hedges instead of walls).
Will I have to loop through all the buildings in the city or is there a way to find the buildingID of a building in the city that has the required buildingclass more directly?
 
I found it simple to get a class of a certain type:
Code:
iBuildingClassType = gc.getBuildingInfo(iBuildingType).getBuildingClassType()
in onBuldingBuild seems to work however the other way round if I want to get the buildingID of an existant buildingClass in a city doesn't seem to work the same way:

Code:
		#Citydefense upgrades			
		iCitydefense3 = gc.getInfoTypeForString('BUILDINGCLASS_HIGHWALLS')	
		iCitydefense2 = gc.getInfoTypeForString('BUILDINGCLASS_CITY_WALLS')	
		iCitydefense1 = gc.getInfoTypeForString('BUILDINGCLASS_WALLS')		
		if iBuildingClassType == iCitydefense3:
			iRazeBuilding = pCity.getBuildingClassType(iCitydefense2).getBuildingType() 
			pCity.setNumRealBuilding(iRazeBuilding), 0)
		if iBuildingClassType == iCitydefense2:
			iRazeBuilding = pCity.getBuildingClassType(iCitydefense1).getBuildingType() 
			pCity.setNumRealBuilding(iRazeBuilding), 0)

returns an error for pCity.setNumRealBuilding(iRazeBuilding), 0). What am I doing wrong?


A "pCity" doesn't know anything about civspecific buildings for a BuildingClass, so your call for pCity.getBuildingClassType... (etc) is probably not returning anything useful. When you pass the returned value (iRazeBuilding) into setNumRealBuilding, it complains because it doesn't know which building should be removed.

The first bit of code you posted was correct though - a BuildingInfo does contain the details of the buildingclass, so we're actually looking for something more like;
Code:
gc.getCivilizationInfo(gc.getPlayer(pCity.getOwner()).getCivilizationType()).getCivilizationBuildings(iCityDefense1)

where iCityDefense1 is the BuildingClass you were looking for.

Ridiculous looking code I know, but it should do it.
Alternatively;

Code:
pPlayer = gc.getPlayer(pCity.getOwner()) # Find the player who owns the city
iCivType = pPlayer.getCivilizationType() # What civilization is that player?
pCivInfo = gc.getCivilizationInfo(iCivType) # Find the information for that civilization
iRazeBuilding = pCivInfo.getCivilizationBuilding(iCityDefense1) # Find which building they use for BUILDINGCLASS_WALLS

which breaks up the line a little...

Either way - it's "theory-code" again - I haven't been able to check it - but it might give you an idea of where to go with it.

===

Failing that - looping through the city as you suggested isn't a bad move either... Possibly even the simpler option...
 
Oh still not working.:p Would getCivilizationBuilding return a buildingID even if that building is not referenced in CivilizationInfos.xml - I guess not, right? So this means I would have to put in the buildings in CivilizationInfos.xml even if a civ gets a default building? Or is there a work around?
 
I've rewritten the code to get around calling civtypes however still no luck:
eventmanager
Code:
	def onBuildingBuilt(self, argsList):
		'Building Completed'
		pCity, iBuildingType = argsList
		player = pCity.getOwner()
		pPlayer = gc.getPlayer(player)
		pPlot = pCity.plot()
		game = gc.getGame()
		iBuildingClassType = gc.getBuildingInfo(iBuildingType).getBuildingClassType()
		


		#Citydefense upgrades			
		iCitydefense3 = gc.getInfoTypeForString('BUILDINGCLASS_HIGH_WALLS')	
		iCitydefense2 = gc.getInfoTypeForString('BUILDINGCLASS_CITY_WALLS')	
		iCitydefense1 = gc.getInfoTypeForString('BUILDINGCLASS_WALLS')		
		if iBuildingClassType == iCitydefense3:
			for iBuilding in range (pCity.getNumBuildings()):
				iBuildingClass = gc.getBuildingInfo(iBuilding).getBuildingClassType()
				if iBuildingClass == iCitydefense2:
					pCity.setNumRealBuilding(iBuilding, 0)
		if iBuildingClassType == iCitydefense2:
			for iBuilding in range (pCity.getNumBuildings()):
				iBuildingClass = gc.getBuildingInfo(iBuilding).getBuildingClassType()
				if iBuildingClass == iCitydefense1:
					pCity.setNumRealBuilding(iBuilding, 0)

and in gameutils
Code:
	def cannotConstruct(self,argsList):
		pCity = argsList[0]
		eBuilding = argsList[1]
		bContinue = argsList[2]
		bTestVisible = argsList[3]
		bIgnoreCost = argsList[4]
		pPlayer = gc.getPlayer(pCity.getOwner())
		eBuildingClass = gc.getBuildingInfo(eBuilding).getBuildingClassType()

		icitydefense1 = gc.getInfoTypeForString('BUILDINGCLASS_WALLS')
		icitydefense2 = gc.getInfoTypeForString('BUILDINGCLASS_CITY_WALLS')
		icitydefense3 = gc.getInfoTypeForString('BUILDINGCLASS_HIGH_WALLS')
		iCastle = gc.getInfoTypeForString('BUILDINGCLASS_CASTLE')
		iCitadel = gc.getInfoTypeForString('BUILDINGCLASS_CITADEL')

		if eBuildingClass == icitydefense1:
			for iBuilding in range (pCity.getNumBuildings()):
				iBuildingClass = gc.getBuildingInfo(iBuilding).getBuildingClassType()
				if iBuildingClass == icitydefense2 or icitydefense3:
					return True
		if eBuildingClass == icitydefense2:
			for iBuilding in range (pCity.getNumBuildings()):
				iBuildingClass = gc.getBuildingInfo(iBuilding).getBuildingClassType()
				if iBuildingClass == icitydefense3:
					return True
the weird thing is I can't build walls in my capital. The other walltypes aren't buildable at all. It's probably wrong to use getNumBuildings in the loop but I can't find an attribute in cyCity to call all the buildings inside a city. Can anyone help please?
 
range(pCity.getNumBuildings()) doesn't return the list of building ID but [0,1,2,..] .

This should work :

Spoiler :
Code:
	def onBuildingBuilt(self, argsList):
		'Building Completed'
		pCity, iBuildingType = argsList
		player = pCity.getOwner()
		pPlayer = gc.getPlayer(player)
		pPlot = pCity.plot()
		game = gc.getGame()
		iBuildingClassType = gc.getBuildingInfo(iBuildingType).getBuildingClassType()

		#Citydefense upgrades			
		iCitydefense3 = gc.getInfoTypeForString('BUILDINGCLASS_HIGH_WALLS')	
		iCitydefense2 = gc.getInfoTypeForString('BUILDINGCLASS_CITY_WALLS')	
		iCitydefense1 = gc.getInfoTypeForString('BUILDINGCLASS_WALLS')		
		if iBuildingClassType == iCitydefense3:
			for iBuilding in range(gc.getNumBuildingInfos()) :
                                if pCity.getNumRealBuilding(iBuilding) > 0 :
                                        iBuildingClass = gc.getBuildingInfo(iBuilding).getBuildingClassType()
                                        if iBuildingClass == iCitydefense2:
                                                pCity.setNumRealBuilding(iBuilding, 0)
		elif iBuildingClassType == iCitydefense2:
			for iBuilding in range(gc.getNumBuildingInfos()) :
                                if pCity.getNumRealBuilding(iBuilding) > 0 :
                                        iBuildingClass = gc.getBuildingInfo(iBuilding).getBuildingClassType()
                                        if iBuildingClass == iCitydefense1:
                                                pCity.setNumRealBuilding(iBuilding, 0)

Tcho !

Edit : be careful with some codes :

Code:
				if iBuildingClass == icitydefense2 or icitydefense3:
					return True

if icitydefense3 = 0 (0 = False), the test will pass only if iBuildingClass = icitydefense2 . and if icitydefense3 > 0 , the test will be always True ((icitydefense3 != 0 or icitydefense3 != None)= True) . This should be "if iBuildingClass == icitydefense2 or iBuildingClass == icitydefense3:"
 
if icitydefense3 = 0 (0 = False), the test will pass only if iBuildingClass = icitydefense2 . and if icitydefense3 > 0 , the test will be always True ((icitydefense3 != 0 or icitydefense3 != None)= True) . This should be "if iBuildingClass == icitydefense2 or iBuildingClass == icitydefense3:"

Damn I still don't think even close to programmer that's what I allways learn from your posts:D Thank you, Sto!
 
I still can't build walls in my capital and the second city refused to build tier2 walls. Apart from that it seems to work in other cities I could build walls and second tier walls which removed the previous ones. This is really weird:(
 
Back
Top Bottom