• Our friends from AlphaCentauri2.info are in need of technical assistance. If you have experience with the LAMP stack and some hours to spare, please help them out and post here.

[PYTHON] "cannotConstruct" function for team/player possible ?

xaster

Warlord
Joined
Oct 5, 2003
Messages
128
Hi All,
i hope somebody can help me. I try to adjust the code function from CvGameUtils.py a little bit.
I have two national wonders. But I plan to allow only one of this wonders at a time.
Player must decide which one is preferred. For example:
If BUILDING_XXX is build you cannot get BUILDING_ZZZ and reverse....
I know this function from Next War Mod and it is working in a single city. Can I use it for a team or player ???

Code:
def cannotConstruct(self,argsList):
        pCity = argsList[0]
        eBuilding = argsList[1]
        bContinue = argsList[2]
        bTestVisible = argsList[3]
        bIgnoreCost = argsList[4]
        
        #TEST
        if eBuilding == gc.getInfoTypeForString("BUILDING_XXX"):
            if pCity.getNumRealBuilding(gc.getInfoTypeForString("BUILDING_ZZZ")):
                return True

        #TEST
        if eBuilding == gc.getInfoTypeForString("BUILDING_ZZZ"):
            if pCity.getNumRealBuilding(gc.getInfoTypeForString("BUILDING_XXX")):
                return True

        return False

Cheers
Xas
 
Yes, it would be possible to have two buildings where one player can only have one.

What you need to do would be something like this: (if I get the function right. I didn't verify everything)
  1. cache building IDs, like eBuildingXXX = gc.getInfoTypeForString("BUILDING_XXX")
  2. return False if eBuilding is not of the type of any of the two buildings
  3. get owner from city
  4. return True if owner.countNumBuildings(eBuildingXXX) > 0, repeat for YYY
  5. return False
The question is how much it will affect performance. I think it will be hard to optimize more than what I have written here unless you modify the DLL itself. Still it's an often used function, meaning it is nearly impossible not to slow down the game.
 
Puhh, it seems this is nothing für the CvGameUtils.py function?!?
More the CvEventmanager.....
Iam defently not a mastermind in coding.
may you can write me that block please.
So i van check this about the performance and so on.
 
Maybe it is a better way to do it in the "CvEventManager.py" by using the "def onBuildingBuilt" function :)
I just copy the code from Next War Arcology. It is working for XXX and ZZZ in a single city. So XXX will always replace ZZZ and reverse.

Code:
    def onBuildingBuilt(self, argsList):
        'Building Completed'
        pCity, iBuildingType = argsList
        game = gc.getGame()
        if pCity.getOwner() == gc.getGame().getActivePlayer() and gc.getBuildingInfo(iBuildingType).getMovieDefineTag() != "NONE":
            # If this is a wonder...
            popupInfo = CyPopupInfo()
            popupInfo.setButtonPopupType(ButtonPopupTypes.BUTTONPOPUP_PYTHON_SCREEN)
            popupInfo.setData1(iBuildingType)
            popupInfo.setData2(pCity.getID())
            popupInfo.setData3(0)
            popupInfo.setText(u"showWonderMovie")
            popupInfo.addPopup(pCity.getOwner())

        CvAdvisorUtils.buildingBuiltFeats(pCity, iBuildingType)

#replace ARCOLOGY with higher level     
        if iBuildingType == CvUtil.findInfoTypeNum(gc.getBuildingInfo, gc.getNumBuildingInfos(), "BUILDING_ARCOLOGY_SHIELDING"):
            pCity.setNumRealBuilding(CvUtil.findInfoTypeNum(gc.getBuildingInfo, gc.getNumBuildingInfos(), "BUILDING_ARCOLOGY"), False)
        elif iBuildingType == CvUtil.findInfoTypeNum(gc.getBuildingInfo, gc.getNumBuildingInfos(), "BUILDING_DEFLECTOR_SHIELDING"):
            pCity.setNumRealBuilding(CvUtil.findInfoTypeNum(gc.getBuildingInfo, gc.getNumBuildingInfos(), "BUILDING_ARCOLOGY_SHIELDING"), False)

#TEST         
        elif iBuildingType == CvUtil.findInfoTypeNum(gc.getBuildingInfo, gc.getNumBuildingInfos(), "BUILDING_XXX"):
            pCity.setNumRealBuilding(CvUtil.findInfoTypeNum(gc.getBuildingInfo, gc.getNumBuildingInfos(), "BUILDING_ZZZ"), False)
        elif iBuildingType == CvUtil.findInfoTypeNum(gc.getBuildingInfo, gc.getNumBuildingInfos(), "BUILDING_ZZZ"):
            pCity.setNumRealBuilding(CvUtil.findInfoTypeNum(gc.getBuildingInfo, gc.getNumBuildingInfos(), "BUILDING_XXX"), False)
#TEST END


How can i make this global for all player citys :dunno::hmm::help:

EDIT: I found a gap workaround due to XML :lol: ( It is more my field because of my less C++ coding skills :hammer2: )
In fact that the building replacment is working with this code at one city i just limited BUILDING_XXX and ZZZ to a BuildingClassNeededs = BUILDINGCLASS_HEROIC_EPIC
and adjusted in Global Defines the tag MAX_NATIONAL_WONDERS_PER_CITY to 5.
Now the player have to choose if he like BUILDING_XXX or ZZZ :run:
I know this is not a pretty solution but works for the moment.

Maybe somebody have an idea to adjust the CvEventManager.py code, this would be more fantastic :help:
 
Last edited:
The german colleagues found a solution about this task in CvEventManager.py and this function

Code:
def onBuildingBuilt(self, argsList):
        'Building Completed'
        pCity, iBuildingType = argsList
#add "pPlayer" for function below
        pPlayer = gc.getPlayer(pCity.getOwner())

        elif iBuildingType == gc.getInfoTypeForString("BUILDING_XXX"):
            (loopCity, iter) = (pPlayer.firstCity(True))
            while(loopCity):
                loopCity.setNumRealBuilding(gc.getInfoTypeForString("BUILDING_ZZZ"), False)
                (loopCity, iter) = (pPlayer.nextCity(iter, true))
        elif iBuildingType == gc.getInfoTypeForString("BUILDING_ZZZ"):
            (loopCity, iter) = (pPlayer.firstCity(True))
            while(loopCity):
                loopCity.setNumRealBuilding(gc.getInfoTypeForString("BUILDING_XXX"), False)
                (loopCity, iter) = (pPlayer.nextCity(iter, true))

For information, maybe somebody have the same problems and can use it.
 
Back
Top Bottom