Quick Modding Questions Thread

Is there a Python event to be handled when the Python code is read again?
 
Is there a Python event to be handled when the Python code is read again?
In case anyone else is wondering about that, if you use BUG, there is a "PythonReloaded" event you can hook up to that is fired every time the game refreshes and reinitialises the Python code.
 
How do you get a graphical effect to continually loop?? (I feel like it should be obvious...)
 
No, wait, I know how to do it. In CvEventManager there is a function called "update" that you can put looping/constant things in. So a looping graphical effect could be done by putting triggerEffect in update().

Edit: it seems that the function you should use is onGameUpdate()
 
Last edited:
Hi!

Can someone tell me where the size of tech icon is set for the Tech Tree screen?
I want to change this look in AND2
upload_2018-7-31_12-50-46-png.500614
into this look
upload_2018-7-31_12-51-46-png.500615


This is the CvTechChooser.py I want to edit:

Code:
## Sid Meier's Civilization 4
## Copyright Firaxis Games 2005
from CvPythonExtensions import *
import CvUtil
import ScreenInput
import CvScreenEnums
import CvScreensInterface

TEXTURE_SIZE = 24
X_START = 6
#X_INCREMENT = 27 # default BUG 27
X_INCREMENT = 24 # default BUG 27
Y_ROW = 32

CIV_HAS_TECH = 0
CIV_IS_RESEARCHING = 1
CIV_NO_RESEARCH = 2
CIV_TECH_AVAILABLE = 3

# globals
gc = CyGlobalContext()
ArtFileMgr = CyArtFileMgr()
localText = CyTranslator()

# BUG - GP Tech Prefs - start
import TechPrefs
import BugCore
BugOpt = BugCore.game.Advisors
ClockOpt = BugCore.game.NJAGC

import BugUtil

PREF_ICON_SIZE = 24
PREF_ICON_TOP = 168
PREF_ICON_LEFT = 10

FLAVORS = [ TechPrefs.FLAVOR_PRODUCTION, TechPrefs.FLAVOR_GOLD, TechPrefs.FLAVOR_SCIENCE,
            TechPrefs.FLAVOR_CULTURE, TechPrefs.FLAVOR_RELIGION, TechPrefs.FLAVOR_MILITARY,
            TechPrefs.FLAVOR_ESPIONAGE]
UNIT_CLASSES = [ "UNITCLASS_ENGINEER", "UNITCLASS_MERCHANT", "UNITCLASS_SCIENTIST",
                 "UNITCLASS_ARTIST", "UNITCLASS_PROPHET", "UNITCLASS_GREAT_GENERAL",
                 "UNITCLASS_GREAT_SPY"]
# BUG - GP Tech Prefs - end

# BUG - 3.19 No Espionage - start
import GameUtil
# BUG - 3.19 No Espionage - end

# BUG - Mac Support - start
BugUtil.fixSets(globals())
# BUG - Mac Support - end

# Rise of Mankind 2.91 - tech tree colors - start
RoMOpt = BugCore.game.RoMSettings
# Rise of Mankind 2.91 - tech tree colors - end

# BUG - Tech Era Colors - start
def getEraDescription(eWidgetType, iData1, iData2, bOption):
    return gc.getEraInfo(iData1).getDescription()
# BUG - Tech Era Colors - end

# BUG - GP Tech Prefs - start
def resetTechPrefs(args=[]):
    CvScreensInterface.techChooser.resetTechPrefs()

def getAllTechPrefsHover(widgetType, iData1, iData2, bOption):
    return buildTechPrefsHover("TXT_KEY_BUG_TECH_PREFS_ALL", CvScreensInterface.techChooser.pPrefs.getAllFlavorTechs(iData1))

def getCurrentTechPrefsHover(widgetType, iData1, iData2, bOption):
    return buildTechPrefsHover("TXT_KEY_BUG_TECH_PREFS_CURRENT", CvScreensInterface.techChooser.pPrefs.getCurrentFlavorTechs(iData1))

def getFutureTechPrefsHover(widgetType, iData1, iData2, bOption):
    pPlayer = gc.getPlayer(CvScreensInterface.techChooser.iCivSelected)
    sTechs = set()
    for i in range(gc.getNumTechInfos()):
        if (pPlayer.isResearchingTech(i)):
            sTechs.add(CvScreensInterface.techChooser.pPrefs.getTech(i))
    return buildTechPrefsHover("TXT_KEY_BUG_TECH_PREFS_FUTURE", CvScreensInterface.techChooser.pPrefs.getCurrentWithFlavorTechs(iData1, sTechs))

def buildTechPrefsHover(key, lTechs):
    szText = BugUtil.getPlainText(key) + "\n"
    for pTech in lTechs:
        szText += "<img=%s size=24></img>" % pTech.getInfo().getButton().replace(" ", "_")
    return szText
# BUG - GP Tech Prefs - end

class CvTechChooser:
    "Tech Chooser Screen"

    def __init__(self):
        self.nWidgetCount = 0
        self.iCivSelected = 0
        self.aiCurrentState = []

        # Advanced Start
        self.m_iSelectedTech = -1
        self.m_bSelectedTechDirty = False
        self.m_bTechRecordsDirty = False

# BUG - GP Tech Prefs - start
        self.bPrefsShowing = False
        self.resetTechPrefs()
# BUG - GP Tech Prefs - end
# Rise of Mankind 2.7 - more techs vertically
#        self.PIXEL_INCREMENT = 7 # BUG default 7
        self.PIXEL_INCREMENT = 10 # BUG default 7
        self.BOX_INCREMENT_WIDTH = 24 # Used to be 33 #Should be a multiple of 3...

#        self.BOX_INCREMENT_HEIGHT = 9 #Should be a multiple of 3...
        self.BOX_INCREMENT_HEIGHT = 6 #Should be a multiple of 3...
#        self.BOX_INCREMENT_Y_SPACING = 6 #Should be a multiple of 3...
        self.BOX_INCREMENT_Y_SPACING = 3 #Should be a multiple of 3...
# Rise of Mankind 2.7 - more techs vertically
        self.BOX_INCREMENT_X_SPACING = 9 # default 9, Should be a multiple of 3...

    def getScreen(self):
        return CyGInterfaceScreen( "TechChooser", CvScreenEnums.TECH_CHOOSER )

    def hideScreen (self):
        # Get the screen
        screen = self.getScreen()

        # Hide the screen
        screen.hideScreen()

    # Screen construction function
    def interfaceScreen(self):
#        BugUtil.debug("CvTechChooser: interfacescreen")
#        self.timer = BugUtil.Timer("CvTechChooser")

        if ( CyGame().isPitbossHost() ):
            return

        # Create a new screen, called TechChooser, using the file CvTechChooser.py for input
        screen = self.getScreen()
        screen.setRenderInterfaceOnly(True)
        screen.showScreen(PopupStates.POPUPSTATE_IMMEDIATE, False)

        screen.hide("AddTechButton")
        screen.hide("ASPointsLabel")
        screen.hide("SelectedTechLabel")

# BUG - GP Tech Prefs - start
        self.NO_TECH_ART = ArtFileMgr.getInterfaceArtInfo("INTERFACE_BUTTONS_CANCEL").getPath()
# BUG - GP Tech Prefs - end
           
        if ( CyGame().cheatCodesEnabled() or gc.getTeam(gc.getGame().getActiveTeam()).getNumMembers() > 1):
            screen.addDropDownBoxGFC( "CivDropDown", 22, 12, 192, WidgetTypes.WIDGET_GENERAL, -1, -1, FontTypes.SMALL_FONT )
            screen.setActivation( "CivDropDown", ActivationTypes.ACTIVATE_MIMICPARENTFOCUS )
            for j in range(gc.getMAX_PLAYERS()):
                if (gc.getPlayer(j).isAlive()):
                    if (CyGame().cheatCodesEnabled() or gc.getPlayer(j).getTeam() == gc.getGame().getActiveTeam()):
                        screen.addPullDownString( "CivDropDown", gc.getPlayer(j).getName(), j, j, False )
        else:
            screen.hide( "CivDropDown" )

        if ( screen.isPersistent() and self.iCivSelected == gc.getGame().getActivePlayer()):
            self.updateTechRecords(False)
            return

        self.nWidgetCount = 0
        self.sWidgets = []

        self.iCivSelected = gc.getGame().getActivePlayer()
        self.aiCurrentState = []
        screen.setPersistent( True )

        # Advanced Start
        if (gc.getPlayer(self.iCivSelected).getAdvancedStartPoints() >= 0):

            self.m_bSelectedTechDirty = True

            self.X_ADD_TECH_BUTTON = 10
            self.Y_ADD_TECH_BUTTON = 731
            self.W_ADD_TECH_BUTTON = 150
            self.H_ADD_TECH_BUTTON = 30
            self.X_ADVANCED_START_TEXT = self.X_ADD_TECH_BUTTON + self.W_ADD_TECH_BUTTON + 20

            szText = localText.getText("TXT_KEY_WB_AS_ADD_TECH", ())
            screen.setButtonGFC( "AddTechButton", szText, "", self.X_ADD_TECH_BUTTON, self.Y_ADD_TECH_BUTTON, self.W_ADD_TECH_BUTTON, self.H_ADD_TECH_BUTTON, WidgetTypes.WIDGET_GENERAL, -1, -1, ButtonStyles.BUTTON_STYLE_STANDARD )
            screen.hide("AddTechButton")

# BUG - Tech Screen Resolution - start
        if (BugOpt.isWideTechScreen() and screen.getXResolution() > 1024):
            xPanelWidth = screen.getXResolution() - 60
        else:
            xPanelWidth = 1024
        yPanelHeight = 768

        screen.showWindowBackground( False )
        screen.setDimensions((screen.getXResolution() - xPanelWidth) / 2, screen.centerY(0), xPanelWidth, yPanelHeight)
# BUG - Tech Screen Resolution - end

        screen.addPanel( "TechTopPanel", u"", u"", True, False, 0, 0, xPanelWidth, 55, PanelStyles.PANEL_STYLE_TOPBAR )
        screen.addDDSGFC("TechBG", ArtFileMgr.getInterfaceArtInfo("SCREEN_BG_OPAQUE").getPath(), 0, 51, xPanelWidth, yPanelHeight - 96, WidgetTypes.WIDGET_GENERAL, -1, -1 )
        screen.addPanel( "TechBottomPanel", u"", u"", True, False, 0, yPanelHeight - 55, xPanelWidth, 55, PanelStyles.PANEL_STYLE_BOTTOMBAR )
        screen.setText( "TechChooserExit", "Background", u"<font=4>" + CyTranslator().getText("TXT_KEY_PEDIA_SCREEN_EXIT", ()).upper() + "</font>", CvUtil.FONT_RIGHT_JUSTIFY, xPanelWidth - 30, yPanelHeight - 42, 0, FontTypes.TITLE_FONT, WidgetTypes.WIDGET_CLOSE_SCREEN, -1, -1 )
        screen.setActivation( "TechChooserExit", ActivationTypes.ACTIVATE_MIMICPARENTFOCUS )

        # Header...
        szText = u"<font=4>"
        szText = szText + localText.getText("TXT_KEY_TECH_CHOOSER_TITLE", ()).upper()
        szText = szText + u"</font>"
        screen.setLabel( "TechTitleHeader", "Background", szText, CvUtil.FONT_CENTER_JUSTIFY, xPanelWidth / 2, 8, 0, FontTypes.TITLE_FONT, WidgetTypes.WIDGET_GENERAL, -1, -1 )

        # Make the scrollable area for the city list...
        if BugOpt.isShowGPTechPrefs():
            iX = 80
            iW = xPanelWidth - 80
        else:
            iX = 0
            iW = xPanelWidth

        self.TabPanels = ["TechList", "TechTrade"]

        screen.addScrollPanel(self.TabPanels[0], u"", iX, 64, iW, yPanelHeight - 142, PanelStyles.PANEL_STYLE_EXTERNAL )
        screen.setActivation(self.TabPanels[0], ActivationTypes.ACTIVATE_NORMAL )

        screen.addScrollPanel(self.TabPanels[1], u"", 80, 64, xPanelWidth - 80, yPanelHeight - 142, PanelStyles.PANEL_STYLE_EXTERNAL )
        screen.setActivation(self.TabPanels[1], ActivationTypes.ACTIVATE_NORMAL )

# BUG - GP Tech Prefs - start
        if BugOpt.isShowGPTechPrefs():
            screen.addPanel("GPTechPref", u"", u"", True, False, 0, 51, 80, yPanelHeight - 95, PanelStyles.PANEL_STYLE_MAIN_WHITE )
# BUG - GP Tech Prefs - end

        # Add the Highlight
        #screen.addDDSGFC( "TechHighlight", ArtFileMgr.getInterfaceArtInfo("TECH_HIGHLIGHT").getPath(), 0, 0, self.getXStart() + 6, 12 + ( self.BOX_INCREMENT_HEIGHT * self.PIXEL_INCREMENT ), WidgetTypes.WIDGET_GENERAL, -1, -1 )
        #screen.hide( "TechHighlight" )

        self.X_SELECT_TAB = 30
        self.X_TRADE_TAB = 165
        self.Y_TABS = 730

        self.sTechSelectTab = self.getNextWidgetName("TechSelectTab")
        self.sTechTradeTab = self.getNextWidgetName("TechTradeTab")
        self.sTechTabID = self.sTechSelectTab

        # reset widget array so that the above never get deleted
        self.nWidgetCount = 0
        self.sWidgets = []

        self.ConstructTabs()

        self.ShowTab()

        return

    def ConstructTabs(self):
#        BugUtil.debug("cvTechChooser: ConstructTabs")

        screen = self.getScreen()

# Rise of Mankind 2.7
#        self.BOX_INCREMENT_WIDTH = 33 # Used to be 33 #Should be a multiple of 3...
        self.BOX_INCREMENT_WIDTH = 24 # Used to be 33 #Should be a multiple of 3...
# Rise of Mankind 2.7
        self.DrawTechChooser(screen, self.TabPanels[0], True, True, True, True, True, True)




        self.BOX_INCREMENT_WIDTH = 12 # Used to be 33 #Should be a multiple of 3... BUG default 12
        self.DrawTechChooser(screen, self.TabPanels[1], True, False, True, False, False, True)
# Rise of Mankind 2.7      
#        self.BOX_INCREMENT_WIDTH = 33 # Used to be 33 #Should be a multiple of 3...
        self.BOX_INCREMENT_WIDTH = 24 # Used to be 33 #Should be a multiple of 3...
# Rise of Mankind 2.7
#    def DrawTechChooser(self, screen, sPanel, bTechPanel, bTechName, bTechIcon, bTechDetails, bANDPreReq, bORPreReq):



    def ShowTab(self):
#        BugUtil.debug("cvTechChooser: ShowTab")

        screen = self.getScreen()

        for tp in self.TabPanels:
            screen.hide(tp)

        # remove these 2 lines when we return to multi-tab screen and uncomment out the 10 below.
        screen.show(self.TabPanels[0])
        screen.setFocus(self.TabPanels[0])

#        if(self.sTechTabID == self.sTechSelectTab):
#            screen.setText(self.sTechSelectTab, "", "Tech Select", CvUtil.FONT_LEFT_JUSTIFY, self.X_SELECT_TAB, self.Y_TABS, 0, FontTypes.TITLE_FONT, WidgetTypes.WIDGET_GENERAL, -1, -1)
#            screen.setText(self.sTechTradeTab, "", "Tech Trade - under development", CvUtil.FONT_LEFT_JUSTIFY, self.X_TRADE_TAB, self.Y_TABS, 0, FontTypes.TITLE_FONT, WidgetTypes.WIDGET_GENERAL, -1, -1)
#            screen.show(self.TabPanels[0])
#            screen.setFocus(self.TabPanels[0])

#        elif(self.sTechTabID == self.sTechTradeTab):
#            screen.setText(self.sTechSelectTab, "", "Tech Select", CvUtil.FONT_LEFT_JUSTIFY, self.X_SELECT_TAB, self.Y_TABS, 0, FontTypes.TITLE_FONT, WidgetTypes.WIDGET_GENERAL, -1, -1)
#            screen.setText(self.sTechTradeTab, "", "Tech Trade - under development", CvUtil.FONT_LEFT_JUSTIFY, self.X_TRADE_TAB, self.Y_TABS, 0, FontTypes.TITLE_FONT, WidgetTypes.WIDGET_GENERAL, -1, -1)
#            screen.show(self.TabPanels[1])
#            screen.setFocus(self.TabPanels[1])


    def DrawTechChooser(self, screen, sPanel, bTechPanel, bTechName, bTechIcon, bTechDetails, bANDPreReq, bORPreReq):
#        BugUtil.debug("cvTechChooser: DrawTechChooser (%s)", sPanel)
#        self.timer.reset()
#        self.timer.start()

        # Place the tech blocks
        self.placeTechs(screen, sPanel, bTechPanel, bTechName, bTechIcon, bTechDetails)

        # Draw the arrows
        self.drawArrows(screen, sPanel, bANDPreReq, bORPreReq)

        self.updateTechPrefs()

        screen.moveToFront( "CivDropDown" )

        screen.moveToFront( "AddTechButton" )

#        self.timer.logSpan("total")

    def placeTechs(self, screen, sPanel, bTechPanel, bTechName, bTechIcon, bTechDetails):
#        BugUtil.debug("cvTechChooser: placeTechs")

        iMaxX = 0
        iMaxY = 0

        if sPanel == self.TabPanels[0]:
            sPanelWidget = ""
        else:
            sPanelWidget = sPanel

        # If we are the Pitboss, we don't want to put up an interface at all
        if ( CyGame().isPitbossHost() ):
            return

        # Cache some tech infos
        self.createTechInfoCache()

        # Go through all the techs
        for i in range(gc.getNumTechInfos()):

#Afforess Skip Mountaineering w/o Mountains Mod
            if (not gc.getPlayer(0).canEverResearch(i)) : continue
            # Create and place a tech in its proper location
            iX = 30 + ( (gc.getTechInfo(i).getGridX() - 1) * ( ( self.BOX_INCREMENT_X_SPACING + self.BOX_INCREMENT_WIDTH ) * self.PIXEL_INCREMENT ) )
# Rise of Mankind 2.7 - more techs vertically
#            iY = ( gc.getTechInfo(i).getGridY() - 1 ) * ( self.BOX_INCREMENT_Y_SPACING * self.PIXEL_INCREMENT ) + 5
            iY = ( gc.getTechInfo(i).getGridY() - 1 ) * ( self.BOX_INCREMENT_Y_SPACING * self.PIXEL_INCREMENT )
# Rise of Mankind 2.7 - more techs vertically
            szTechRecord = sPanelWidget + "TechRecord" + str(i)

            if ( iMaxX < iX + self.getXStart() ):
                iMaxX = iX + self.getXStart()
            if ( iMaxY < iY + ( self.BOX_INCREMENT_HEIGHT * self.PIXEL_INCREMENT ) ):
                iMaxY = iY + ( self.BOX_INCREMENT_HEIGHT * self.PIXEL_INCREMENT )

# BUG - Tech Era Colors - start
            szTechRecordShadow = sPanelWidget + "TechRecordShadow" + str(i)
            iShadowOffset = 9
            screen.attachPanelAt( sPanel, szTechRecordShadow, u"", u"", True, False, PanelStyles.PANEL_STYLE_TECH, iX - 6 + iShadowOffset, iY - 6 + iShadowOffset, self.getXStart() + 6, 12 + ( self.BOX_INCREMENT_HEIGHT * self.PIXEL_INCREMENT ), WidgetTypes.WIDGET_TECH_CHOOSER_ERA, gc.getTechInfo(i).getEra(), -1 )
            self.setTechPanelShadowColor(screen, szTechRecordShadow, gc.getTechInfo(i).getEra())
            screen.hide( szTechRecordShadow )
# BUG - Tech Era Colors - end

            screen.attachPanelAt( sPanel, szTechRecord, u"", u"", True, False, PanelStyles.PANEL_STYLE_TECH, iX - 6, iY - 6, self.getXStart() + 6, 12 + ( self.BOX_INCREMENT_HEIGHT * self.PIXEL_INCREMENT ), WidgetTypes.WIDGET_TECH_TREE, i, -1 )
            screen.setActivation( szTechRecord, ActivationTypes.ACTIVATE_MIMICPARENTFOCUS)
            screen.hide( szTechRecord )

            #reset so that it offsets from the tech record's panel
            iX = 6
            iY = 6

            if ( gc.getTeam(gc.getPlayer(self.iCivSelected).getTeam()).isHasTech(i) ):
                screen.setPanelColor(szTechRecord, 0, 0, 0)
                self.aiCurrentState.append(CIV_HAS_TECH)
            elif ( gc.getPlayer(self.iCivSelected).getCurrentResearch() == i ):
                screen.setPanelColor(szTechRecord, 0, 0, 200)
                self.aiCurrentState.append(CIV_IS_RESEARCHING)
            elif ( gc.getPlayer(self.iCivSelected).isResearchingTech(i) ):
                screen.setPanelColor(szTechRecord, 200, 0, 0)
                self.aiCurrentState.append(CIV_IS_RESEARCHING)
            elif ( gc.getPlayer(self.iCivSelected).canEverResearch(i) ):
# Rise of Mankind 2.91 - tech tree colors - start
                if (RoMOpt.isRoMTechTreeColors()):
                    # Ancient Era
                    if ( gc.getTechInfo(i).getEra() == 0 ):
                        screen.setPanelColor(szTechRecord, 160, 100, 160)
                    # Classical Era
                    elif ( gc.getTechInfo(i).getEra() == 1 ):
                        screen.setPanelColor(szTechRecord, 160, 100, 100)
                    # Medieval Era
                    elif ( gc.getTechInfo(i).getEra() == 2 ):
                        screen.setPanelColor(szTechRecord, 160, 160, 100)
                    # Renaissance Era
                    elif ( gc.getTechInfo(i).getEra() == 3 ):
                        screen.setPanelColor(szTechRecord, 160, 160, 50)
                    # Industrial Era
                    elif ( gc.getTechInfo(i).getEra() == 4 ):
                        screen.setPanelColor(szTechRecord, 60, 200, 60)
                    # Modern Era
                    elif ( gc.getTechInfo(i).getEra() == 5 ):
                        screen.setPanelColor(szTechRecord, 100, 104, 160)
                    # Future Era
                    else:
                        screen.setPanelColor(szTechRecord, 50, 160, 250)
                else:
                    screen.setPanelColor(szTechRecord, 100, 104, 160)
# Rise of Mankind 2.91 - tech tree colors - end
                self.aiCurrentState.append(CIV_NO_RESEARCH)
            else:
                screen.setPanelColor(szTechRecord, 206, 65, 69)
                self.aiCurrentState.append(CIV_TECH_AVAILABLE)

            if bTechName:
                szTechID = sPanelWidget + "TechID" + str(i)
                szTechString = "<font=1>"
                if ( gc.getPlayer(self.iCivSelected).isResearchingTech(i) ):
                    szTechString = szTechString + str(gc.getPlayer(self.iCivSelected).getQueuePosition(i)) + ". "
                szTechString += gc.getTechInfo(i).getDescription()
                szTechString = szTechString + "</font>"
                screen.setTextAt( szTechID, szTechRecord, szTechString, CvUtil.FONT_LEFT_JUSTIFY, iX + 6 + X_INCREMENT, iY + 6, -0.1, FontTypes.SMALL_FONT, WidgetTypes.WIDGET_TECH_TREE, i, -1 )
                screen.setActivation( szTechID, ActivationTypes.ACTIVATE_MIMICPARENTFOCUS )

            if bTechIcon:
                szTechButtonID = sPanelWidget + "TechButtonID" + str(i)
                screen.addDDSGFCAt( szTechButtonID, szTechRecord, gc.getTechInfo(i).getButton(), iX + 6, iY + 6, TEXTURE_SIZE, TEXTURE_SIZE, WidgetTypes.WIDGET_TECH_TREE, i, -1, False )

            if bTechDetails:
                self.addIconsToTechPanel(screen, i, X_START, iX, iY, szTechRecord)

            if bTechPanel:
                if BugOpt.isShowTechEra():
                    screen.show( szTechRecordShadow )
                else:
                    screen.hide( szTechRecordShadow )
                screen.show( szTechRecord )
            else:
                screen.hide( szTechRecordShadow )
                screen.hide( szTechRecord )

        # delete the tech info cache
        self.deleteTechInfoCache()
       
        screen.setViewMin( sPanel, iMaxX + 20, iMaxY + 20 )

        return

   
    def createTechInfoCache(self):
           
        self.UnitCache = dict()
           
        for j in range( gc.getNumUnitClassInfos() ):
            eLoopUnit = gc.getCivilizationInfo(gc.getGame().getActiveCivilizationType()).getCivilizationUnits(j)
            if (gc.getGame().canEverTrain(eLoopUnit)):
                ePrereq = gc.getUnitInfo(eLoopUnit).getPrereqAndTech()
                if (ePrereq != TechTypes.NO_TECH):
                    if (ePrereq not in self.UnitCache):
                        self.UnitCache[ePrereq] = list()
                    self.UnitCache[ePrereq].append(eLoopUnit)
                       
           
        self.BuildingCache = dict()
        self.BuildingObsoleteCache = dict()
       
        for j in range(gc.getNumBuildingClassInfos()):
            eLoopBuilding = gc.getCivilizationInfo(gc.getGame().getActiveCivilizationType()).getCivilizationBuildings(j)

            if (gc.getGame().canEverConstruct(eLoopBuilding)):
                ePrereq = gc.getBuildingInfo(eLoopBuilding).getPrereqAndTech()
                if (ePrereq != TechTypes.NO_TECH):
                    if (ePrereq not in self.BuildingCache):
                        self.BuildingCache[ePrereq] = list()
                    self.BuildingCache[ePrereq].append(eLoopBuilding)
                                           
                eObsolete = gc.getBuildingInfo(eLoopBuilding).getObsoleteTech()
                if (eObsolete != TechTypes.NO_TECH):
                    if (eObsolete not in self.BuildingObsoleteCache):
                        self.BuildingObsoleteCache[eObsolete] = list()
                    self.BuildingObsoleteCache[eObsolete].append(eLoopBuilding)
                                           
               
    def deleteTechInfoCache(self):
        del self.UnitCache
        del self.BuildingCache
        del self.BuildingObsoleteCache
           

    def addIconsToTechPanel(self, screen, i, fX, iX, iY, szTechRecord):
        BugUtil.debug("CvTechChooser: addIconsToTechPanel")

        j = 0
        k = 0
        iCount = 0
        if (not gc.getPlayer(0).canEverResearch(i)):
            return
       
       
        # Unlockable units...
        if (i in self.UnitCache):
            for eLoopUnit in self.UnitCache[i]:
                szUnitButton = self.getNextWidgetName("Unit")
                iCount += 1
                if (iCount < 10):
                    screen.addDDSGFCAt( szUnitButton, szTechRecord, gc.getPlayer(gc.getGame().getActivePlayer()).getUnitButton(eLoopUnit), iX + fX, iY + Y_ROW, TEXTURE_SIZE, TEXTURE_SIZE, WidgetTypes.WIDGET_PEDIA_JUMP_TO_UNIT, eLoopUnit, 1, True )
                    fX += X_INCREMENT
                       
        #for j in range( gc.getNumUnitClassInfos() ):
        #    eLoopUnit = gc.getCivilizationInfo(gc.getGame().getActiveCivilizationType()).getCivilizationUnits(j)
        #    if (gc.getGame().canEverTrain(eLoopUnit)):
        #        if (gc.getUnitInfo(eLoopUnit).getPrereqAndTech() == i):
        #            szUnitButton = self.getNextWidgetName("Unit")
        #            iCount += 1
        #            if (iCount < 10):
        #                screen.addDDSGFCAt( szUnitButton, szTechRecord, gc.getPlayer(gc.getGame().getActivePlayer()).getUnitButton(eLoopUnit), iX + fX, iY + Y_ROW, TEXTURE_SIZE, TEXTURE_SIZE, WidgetTypes.WIDGET_PEDIA_JUMP_TO_UNIT, eLoopUnit, 1, True )
        #                fX += X_INCREMENT

        j = 0
        k = 0
        BugUtil.debug("CvTechChooser: Marker 1")

        # Unlockable Buildings...
        if (i in self.BuildingCache):
            for eLoopBuilding in self.BuildingCache[i]:
                szBuildingButton = self.getNextWidgetName("Building")
                iCount += 1
                if (iCount < 10):
                    screen.addDDSGFCAt( szBuildingButton, szTechRecord, gc.getBuildingInfo(eLoopBuilding).getButton(), iX + fX, iY + Y_ROW, TEXTURE_SIZE, TEXTURE_SIZE, WidgetTypes.WIDGET_PEDIA_JUMP_TO_BUILDING, eLoopBuilding, 1, True )
                    fX += X_INCREMENT
                   
        #for j in range(gc.getNumBuildingClassInfos()):
        #    bTechFound = 0
        #    eLoopBuilding = gc.getCivilizationInfo(gc.getGame().getActiveCivilizationType()).getCivilizationBuildings(j)

        #    if (gc.getGame().canEverConstruct(eLoopBuilding)):
        #        if (gc.getBuildingInfo(eLoopBuilding).getPrereqAndTech() == i):
        #            szBuildingButton = self.getNextWidgetName("Building")
        #            iCount += 1
        #            if (iCount < 10):
        #                screen.addDDSGFCAt( szBuildingButton, szTechRecord, gc.getBuildingInfo(eLoopBuilding).getButton(), iX + fX, iY + Y_ROW, TEXTURE_SIZE, TEXTURE_SIZE, WidgetTypes.WIDGET_PEDIA_JUMP_TO_BUILDING, eLoopBuilding, 1, True )
        #                fX += X_INCREMENT

        j = 0
        k = 0
        BugUtil.debug("CvTechChooser: Marker 2")
        # Obsolete Buildings...
        if (i in self.BuildingObsoleteCache):
            for eLoopBuilding in self.BuildingObsoleteCache[i]:
                # Add obsolete picture here...
                szObsoleteButton = self.getNextWidgetName("Obsolete")
                szObsoleteX = self.getNextWidgetName("ObsoleteX")
                iCount += 1
                if (iCount < 10):
                    screen.addDDSGFCAt( szObsoleteButton, szTechRecord, gc.getBuildingInfo(eLoopBuilding).getButton(), iX + fX, iY + Y_ROW, TEXTURE_SIZE, TEXTURE_SIZE, WidgetTypes.WIDGET_HELP_OBSOLETE, eLoopBuilding, -1, False )
                    screen.addDDSGFCAt( szObsoleteX, szTechRecord, ArtFileMgr.getInterfaceArtInfo("INTERFACE_BUTTONS_RED_X").getPath(), iX + fX, iY + Y_ROW, TEXTURE_SIZE, TEXTURE_SIZE, WidgetTypes.WIDGET_HELP_OBSOLETE, eLoopBuilding, -1, False )
                    fX += X_INCREMENT
                   
        #for j in range(gc.getNumBuildingClassInfos()):
        #    eLoopBuilding = gc.getCivilizationInfo(gc.getPlayer(self.iCivSelected).getCivilizationType()).getCivilizationBuildings(j)

        #    if (gc.getGame().canEverConstruct(eLoopBuilding)):
        #        if (gc.getBuildingInfo(eLoopBuilding).getObsoleteTech() == i):
                    # Add obsolete picture here...
        #            szObsoleteButton = self.getNextWidgetName("Obsolete")
        #            szObsoleteX = self.getNextWidgetName("ObsoleteX")
        #            iCount += 1
        #            if (iCount < 10):
        #                screen.addDDSGFCAt( szObsoleteButton, szTechRecord, gc.getBuildingInfo(eLoopBuilding).getButton(), iX + fX, iY + Y_ROW, TEXTURE_SIZE, TEXTURE_SIZE, WidgetTypes.WIDGET_HELP_OBSOLETE, eLoopBuilding, -1, False )
        #                screen.addDDSGFCAt( szObsoleteX, szTechRecord, ArtFileMgr.getInterfaceArtInfo("INTERFACE_BUTTONS_RED_X").getPath(), iX + fX, iY + Y_ROW, TEXTURE_SIZE, TEXTURE_SIZE, WidgetTypes.WIDGET_HELP_OBSOLETE, eLoopBuilding, -1, False )
        #                fX += X_INCREMENT

        j = 0
        k = 0
        BugUtil.debug("CvTechChooser: Marker 3")
        # Obsolete Bonuses...
        for j in range(gc.getNumBonusInfos()):
            if (gc.getBonusInfo(j).getTechObsolete() == i):
                # Add obsolete picture here...
                szObsoleteButton = self.getNextWidgetName("ObsoleteBonus")
                szObsoleteX = self.getNextWidgetName("ObsoleteXBonus")
                iCount += 1
                if (iCount < 10):
                    screen.addDDSGFCAt( szObsoleteButton, szTechRecord, gc.getBonusInfo(j).getButton(), iX + fX, iY + Y_ROW, TEXTURE_SIZE, TEXTURE_SIZE, WidgetTypes.WIDGET_HELP_OBSOLETE_BONUS, j, -1, False )
                    screen.addDDSGFCAt( szObsoleteX, szTechRecord, ArtFileMgr.getInterfaceArtInfo("INTERFACE_BUTTONS_RED_X").getPath(), iX + fX, iY + Y_ROW, TEXTURE_SIZE, TEXTURE_SIZE, WidgetTypes.WIDGET_HELP_OBSOLETE_BONUS, j, -1, False )
                    fX += X_INCREMENT
                   
        j = 0
        k = 0
        BugUtil.debug("CvTechChooser: Marker 4")
        # Obsolete Monastaries...
        for j in range (gc.getNumSpecialBuildingInfos()):
            if (gc.getSpecialBuildingInfo(j).getObsoleteTech() == i):
                    # Add obsolete picture here...
                    szObsoleteSpecialButton = self.getNextWidgetName("ObsoleteSpecial")
                    szObsoleteSpecialX = self.getNextWidgetName("ObsoleteSpecialX")
                    iCount += 1
                    if (iCount < 10):
                        screen.addDDSGFCAt( szObsoleteSpecialButton, szTechRecord, gc.getSpecialBuildingInfo(j).getButton(), iX + fX, iY + Y_ROW, TEXTURE_SIZE, TEXTURE_SIZE, WidgetTypes.WIDGET_HELP_OBSOLETE_SPECIAL, j, -1, False )
                        screen.addDDSGFCAt( szObsoleteSpecialX, szTechRecord, ArtFileMgr.getInterfaceArtInfo("INTERFACE_BUTTONS_RED_X").getPath(), iX + fX, iY + Y_ROW, TEXTURE_SIZE, TEXTURE_SIZE, WidgetTypes.WIDGET_HELP_OBSOLETE_SPECIAL, j, -1, False )
                        fX += X_INCREMENT

        j = 0
        k = 0
        BugUtil.debug("CvTechChooser: Marker 5")
        # Route movement change
        for j in range(gc.getNumRouteInfos()):
            if ( gc.getRouteInfo(j).getTechMovementChange(i) != 0 ):
                szMoveButton = self.getNextWidgetName("Move")
                iCount += 1
                if (iCount < 10):
                    screen.addDDSGFCAt( szMoveButton, szTechRecord, ArtFileMgr.getInterfaceArtInfo("INTERFACE_TECH_MOVE_BONUS").getPath(), iX + fX, iY + Y_ROW, TEXTURE_SIZE, TEXTURE_SIZE, WidgetTypes.WIDGET_HELP_MOVE_BONUS, i, -1, False )
                    fX += X_INCREMENT

        j = 0
        k = 0
        BugUtil.debug("CvTechChooser: Marker 6")
        # Promotion Info
        for j in range( gc.getNumPromotionInfos() ):
            if ( gc.getPromotionInfo(j).getTechPrereq() == i ):
                szPromotionButton = self.getNextWidgetName("Promotion")
                iCount += 1
                if (iCount < 10):
                    screen.addDDSGFCAt( szPromotionButton, szTechRecord, gc.getPromotionInfo(j).getButton(), iX + fX, iY + Y_ROW, TEXTURE_SIZE, TEXTURE_SIZE, WidgetTypes.WIDGET_PEDIA_JUMP_TO_PROMOTION, j, -1, False )
                    fX += X_INCREMENT
                   
            elif ( gc.getPromotionInfo(j).getObsoleteTech() == i ):
                szPromotionButton = self.getNextWidgetName("Promotion")
                szObsoleteX = self.getNextWidgetName("ObsoleteX")
                iCount += 1
                if (iCount < 10):
                    screen.addDDSGFCAt( szPromotionButton, szTechRecord, gc.getPromotionInfo(j).getButton(), iX + fX, iY + Y_ROW, TEXTURE_SIZE, TEXTURE_SIZE, WidgetTypes.WIDGET_OBSOLETE_PROMOTION, j, -1, False )
                    screen.addDDSGFCAt( szObsoleteX, szTechRecord, ArtFileMgr.getInterfaceArtInfo("INTERFACE_BUTTONS_RED_X").getPath(), iX + fX, iY + Y_ROW, TEXTURE_SIZE, TEXTURE_SIZE, WidgetTypes.WIDGET_OBSOLETE_PROMOTION, j, -1, False )
                    fX += X_INCREMENT
        j = 0
        k = 0
        BugUtil.debug("CvTechChooser: Marker 7")
        # Free unit
        if ( gc.getTechInfo(i).getFirstFreeUnitClass() != UnitClassTypes.NO_UNITCLASS ):
            szFreeUnitButton = self.getNextWidgetName("FreeUnit")
            eLoopUnit = gc.getCivilizationInfo(gc.getGame().getActiveCivilizationType()).getCivilizationUnits(gc.getTechInfo(i).getFirstFreeUnitClass())
            if (eLoopUnit != -1):
# BUG - 3.19 No Espionage - start
                # CvUnitInfo.getEspionagePoints() was added in 319
                if (GameUtil.getVersion() < 319 or gc.getUnitInfo(eLoopUnit).getEspionagePoints() == 0 or not gc.getGame().isOption(GameOptionTypes.GAMEOPTION_NO_ESPIONAGE)):              
# BUG - 3.19 No Espionage - end
                    iCount += 1
                    if (iCount < 10):
                        screen.addDDSGFCAt( szFreeUnitButton, szTechRecord, gc.getPlayer(gc.getGame().getActivePlayer()).getUnitButton(eLoopUnit), iX + fX, iY + Y_ROW, TEXTURE_SIZE, TEXTURE_SIZE, WidgetTypes.WIDGET_HELP_FREE_UNIT, eLoopUnit, i, False )
                        fX += X_INCREMENT

        j = 0
        k = 0
        BugUtil.debug("CvTechChooser: Marker 8")
        # Feature production modifier
        if ( gc.getTechInfo(i).getFeatureProductionModifier() != 0 ):
            szFeatureProductionButton = self.getNextWidgetName("FeatureProduction")
            iCount += 1
            if (iCount < 10):
                screen.addDDSGFCAt( szFeatureProductionButton, szTechRecord, ArtFileMgr.getInterfaceArtInfo("INTERFACE_TECH_FEATURE_PRODUCTION").getPath(), iX + fX, iY + Y_ROW, TEXTURE_SIZE, TEXTURE_SIZE, WidgetTypes.WIDGET_HELP_FEATURE_PRODUCTION, i, -1, False )
                fX += X_INCREMENT

        j = 0
        k = 0
        BugUtil.debug("CvTechChooser: Marker 9")
        # Worker speed
        if ( gc.getTechInfo(i).getWorkerSpeedModifier() != 0 ):
            szWorkerModifierButton = self.getNextWidgetName("Worker")
            iCount += 1
            if (iCount < 10):
                screen.addDDSGFCAt( szWorkerModifierButton, szTechRecord, ArtFileMgr.getInterfaceArtInfo("INTERFACE_TECH_WORKER_SPEED").getPath(), iX + fX, iY + Y_ROW, TEXTURE_SIZE, TEXTURE_SIZE, WidgetTypes.WIDGET_HELP_WORKER_RATE, i, -1, False )
                fX += X_INCREMENT

        j = 0
        k = 0
        BugUtil.debug("CvTechChooser: Marker 10")
        # Trade Routes per City change
        if ( gc.getTechInfo(i).getTradeRoutes() != 0 ):
            szTradeRouteButton = self.getNextWidgetName("TradeRoutes")
            iCount += 1
            if (iCount < 10):
                screen.addDDSGFCAt( szTradeRouteButton, szTechRecord, ArtFileMgr.getInterfaceArtInfo("INTERFACE_TECH_TRADE_ROUTES").getPath(), iX + fX, iY + Y_ROW, TEXTURE_SIZE, TEXTURE_SIZE, WidgetTypes.WIDGET_HELP_TRADE_ROUTES, i, -1, False )
                fX += X_INCREMENT

        j = 0
        k = 0
        BugUtil.debug("CvTechChooser: Marker 11")
        # Health Rate bonus from this tech...
        if ( gc.getTechInfo(i).getHealth() != 0 ):
            szHealthRateButton = self.getNextWidgetName("HealthRate")
            iCount += 1
            if (iCount < 10):
                screen.addDDSGFCAt( szHealthRateButton, szTechRecord, ArtFileMgr.getInterfaceArtInfo("INTERFACE_TECH_HEALTH").getPath(), iX + fX, iY + Y_ROW, TEXTURE_SIZE, TEXTURE_SIZE, WidgetTypes.WIDGET_HELP_HEALTH_RATE, i, -1, False )
                fX += X_INCREMENT

        j = 0
        k = 0
        BugUtil.debug("CvTechChooser: Marker 12")
        # Happiness Rate bonus from this tech...
        if ( gc.getTechInfo(i).getHappiness() != 0 ):
            szHappinessRateButton = self.getNextWidgetName("HappinessRate")
            iCount += 1
            if (iCount < 10):
                screen.addDDSGFCAt( szHappinessRateButton, szTechRecord, ArtFileMgr.getInterfaceArtInfo("INTERFACE_TECH_HAPPINESS").getPath(), iX + fX, iY + Y_ROW, TEXTURE_SIZE, TEXTURE_SIZE, WidgetTypes.WIDGET_HELP_HAPPINESS_RATE, i, -1, False )
                fX += X_INCREMENT

        j = 0
        k = 0
        BugUtil.debug("CvTechChooser: Marker 13")
        # Free Techs
        if ( gc.getTechInfo(i).getFirstFreeTechs() > 0 ):
            szFreeTechButton = self.getNextWidgetName("FreeTech")
            iCount += 1
            if (iCount < 10):
                screen.addDDSGFCAt( szFreeTechButton, szTechRecord, ArtFileMgr.getInterfaceArtInfo("INTERFACE_TECH_FREETECH").getPath(), iX + fX, iY + Y_ROW, TEXTURE_SIZE, TEXTURE_SIZE, WidgetTypes.WIDGET_HELP_FREE_TECH, i, -1, False )
                fX += X_INCREMENT

        j = 0
        k = 0
        BugUtil.debug("CvTechChooser: Marker 14")
        # Line of Sight bonus...
        if ( gc.getTechInfo(i).isExtraWaterSeeFrom() ):
            szLOSButton = self.getNextWidgetName("LOS")
            iCount += 1
            if (iCount < 10):
                screen.addDDSGFCAt( szLOSButton, szTechRecord, ArtFileMgr.getInterfaceArtInfo("INTERFACE_TECH_LOS").getPath(), iX + fX, iY + Y_ROW, TEXTURE_SIZE, TEXTURE_SIZE, WidgetTypes.WIDGET_HELP_LOS_BONUS, i, -1, False )
                fX += X_INCREMENT

        j = 0
        k = 0
        BugUtil.debug("CvTechChooser: Marker 14")
        # Map Center Bonus...
        if ( gc.getTechInfo(i).isMapCentering() ):
            szMapCenterButton = self.getNextWidgetName("MapCenter")
            iCount += 1
            if (iCount < 10):
                screen.addDDSGFCAt( szMapCenterButton, szTechRecord, ArtFileMgr.getInterfaceArtInfo("INTERFACE_TECH_MAPCENTER").getPath(), iX + fX, iY + Y_ROW, TEXTURE_SIZE, TEXTURE_SIZE, WidgetTypes.WIDGET_HELP_MAP_CENTER, i, -1, False )
                fX += X_INCREMENT

        j = 0
        k = 0
        BugUtil.debug("CvTechChooser: Marker 15")
        # Map Reveal...
        if ( gc.getTechInfo(i).isMapVisible() ):
            szMapRevealButton = self.getNextWidgetName("MapReveal")
            iCount += 1
            if (iCount < 10):
                screen.addDDSGFCAt( szMapRevealButton, szTechRecord, ArtFileMgr.getInterfaceArtInfo("INTERFACE_TECH_MAPREVEAL").getPath(), iX + fX, iY + Y_ROW, TEXTURE_SIZE, TEXTURE_SIZE, WidgetTypes.WIDGET_HELP_MAP_REVEAL, i, -1, False )
                fX += X_INCREMENT

        j = 0
        k = 0
        BugUtil.debug("CvTechChooser: Marker 16")
        # Map Trading
        if ( gc.getTechInfo(i).isMapTrading() == True ):
            szMapTradeButton = self.getNextWidgetName("MapTrade")
            iCount += 1
            if (iCount < 10):
                screen.addDDSGFCAt( szMapTradeButton, szTechRecord, ArtFileMgr.getInterfaceArtInfo("INTERFACE_TECH_MAPTRADING").getPath(), iX + fX, iY + Y_ROW, TEXTURE_SIZE, TEXTURE_SIZE, WidgetTypes.WIDGET_HELP_MAP_TRADE, i, -1, False )
                fX += X_INCREMENT

        j = 0
        k = 0
        BugUtil.debug("CvTechChooser: Marker 17")
        # Tech Trading
        if ( gc.getTechInfo(i).isTechTrading() ):
            szTechTradeButton = self.getNextWidgetName("TechTrade")
            iCount += 1
            if (iCount < 10):
                screen.addDDSGFCAt( szTechTradeButton, szTechRecord, ArtFileMgr.getInterfaceArtInfo("INTERFACE_TECH_TECHTRADING").getPath(), iX + fX, iY + Y_ROW, TEXTURE_SIZE, TEXTURE_SIZE, WidgetTypes.WIDGET_HELP_TECH_TRADE, i, -1, False )
                fX += X_INCREMENT

        j = 0
        k = 0
        BugUtil.debug("CvTechChooser: Marker 18")
        # Gold Trading
        if ( gc.getTechInfo(i).isGoldTrading() ):
            szGoldTradeButton = self.getNextWidgetName("GoldTrade")
            iCount += 1
            if (iCount < 10):
                screen.addDDSGFCAt( szGoldTradeButton, szTechRecord, ArtFileMgr.getInterfaceArtInfo("INTERFACE_TECH_GOLDTRADING").getPath(), iX + fX, iY + Y_ROW, TEXTURE_SIZE, TEXTURE_SIZE, WidgetTypes.WIDGET_HELP_GOLD_TRADE, i, -1, False )
                fX += X_INCREMENT

        j = 0
        k = 0
        BugUtil.debug("CvTechChooser: Marker 19")
        # Open Borders
        if ( gc.getTechInfo(i).isOpenBordersTrading() ):
            szOpenBordersButton = self.getNextWidgetName("OpenBorders")
            iCount += 1
            if (iCount < 10):
                screen.addDDSGFCAt( szOpenBordersButton , szTechRecord, ArtFileMgr.getInterfaceArtInfo("INTERFACE_TECH_OPENBORDERS").getPath(), iX + fX, iY + Y_ROW, TEXTURE_SIZE, TEXTURE_SIZE, WidgetTypes.WIDGET_HELP_OPEN_BORDERS, i, -1, False )
                fX += X_INCREMENT

        j = 0
        k = 0
        BugUtil.debug("CvTechChooser: Marker 20")
        # Defensive Pact
        if ( gc.getTechInfo(i).isDefensivePactTrading() ):
            szDefensivePactButton = self.getNextWidgetName("DefensivePact")
            iCount += 1
            if (iCount < 10):
                screen.addDDSGFCAt( szDefensivePactButton , szTechRecord, ArtFileMgr.getInterfaceArtInfo("INTERFACE_TECH_DEFENSIVEPACT").getPath(), iX + fX, iY + Y_ROW, TEXTURE_SIZE, TEXTURE_SIZE, WidgetTypes.WIDGET_HELP_DEFENSIVE_PACT, i, -1, False )
                fX += X_INCREMENT

        j = 0
        k = 0
        BugUtil.debug("CvTechChooser: Marker 21")
        # Permanent Alliance
        if ( gc.getTechInfo(i).isPermanentAllianceTrading() ):
            szPermanentAllianceButton = self.getNextWidgetName("PermanentAlliance")
            iCount += 1
            if (iCount < 10):
                screen.addDDSGFCAt( szPermanentAllianceButton , szTechRecord, ArtFileMgr.getInterfaceArtInfo("INTERFACE_TECH_PERMALLIANCE").getPath(), iX + fX, iY + Y_ROW, TEXTURE_SIZE, TEXTURE_SIZE, WidgetTypes.WIDGET_HELP_PERMANENT_ALLIANCE, i, -1, False )
                fX += X_INCREMENT

        j = 0
        k = 0
        BugUtil.debug("CvTechChooser: Marker 22")
        # Vassal States
        if ( gc.getTechInfo(i).isVassalStateTrading() ):
            szVassalStateButton = self.getNextWidgetName("VassalState")
            iCount += 1
            if (iCount < 10):
                screen.addDDSGFCAt( szVassalStateButton , szTechRecord, ArtFileMgr.getInterfaceArtInfo("INTERFACE_TECH_VASSAL").getPath(), iX + fX, iY + Y_ROW, TEXTURE_SIZE, TEXTURE_SIZE, WidgetTypes.WIDGET_HELP_VASSAL_STATE, i, -1, False )
                fX += X_INCREMENT

        j = 0
        k = 0
        BugUtil.debug("CvTechChooser: Marker 23")
        # Bridge Building
        if ( gc.getTechInfo(i).isBridgeBuilding() ):
            szBuildBridgeButton = self.getNextWidgetName("BuildBridge")
            iCount += 1
            if (iCount < 10):
                screen.addDDSGFCAt( szBuildBridgeButton, szTechRecord, ArtFileMgr.getInterfaceArtInfo("INTERFACE_TECH_BRIDGEBUILDING").getPath(), iX + fX, iY + Y_ROW, TEXTURE_SIZE, TEXTURE_SIZE, WidgetTypes.WIDGET_HELP_BUILD_BRIDGE, i, -1, False )
                fX += X_INCREMENT

        j = 0
        k = 0
        BugUtil.debug("CvTechChooser: Marker 24")
        # Irrigation unlocked...
        if ( gc.getTechInfo(i).isIrrigation() ):
            szIrrigationButton = self.getNextWidgetName("Irrigation")
            iCount += 1
            if (iCount < 10):
                screen.addDDSGFCAt( szIrrigationButton, szTechRecord, ArtFileMgr.getInterfaceArtInfo("INTERFACE_TECH_IRRIGATION").getPath(), iX + fX, iY + Y_ROW, TEXTURE_SIZE, TEXTURE_SIZE, WidgetTypes.WIDGET_HELP_IRRIGATION, i, -1, False )
                fX += X_INCREMENT

        j = 0
        k = 0
        BugUtil.debug("CvTechChooser: Marker 25")
        # Ignore Irrigation unlocked...
        if ( gc.getTechInfo(i).isIgnoreIrrigation() ):
            szIgnoreIrrigationButton = self.getNextWidgetName("IgnoreIrrigation")
            iCount += 1
            if (iCount < 10):
                screen.addDDSGFCAt( szIgnoreIrrigationButton, szTechRecord, ArtFileMgr.getInterfaceArtInfo("INTERFACE_TECH_NOIRRIGATION").getPath(), iX + fX, iY + Y_ROW, TEXTURE_SIZE, TEXTURE_SIZE, WidgetTypes.WIDGET_HELP_IGNORE_IRRIGATION, i, -1, False )
                fX += X_INCREMENT

        j = 0
        k = 0
        BugUtil.debug("CvTechChooser: Marker 26")
        # Coastal Work unlocked...
        if ( gc.getTechInfo(i).isWaterWork() ):
            szWaterWorkButton = self.getNextWidgetName("WaterWork")
            iCount += 1
            if (iCount < 10):
                screen.addDDSGFCAt( szWaterWorkButton, szTechRecord, ArtFileMgr.getInterfaceArtInfo("INTERFACE_TECH_WATERWORK").getPath(), iX + fX, iY + Y_ROW, TEXTURE_SIZE, TEXTURE_SIZE, WidgetTypes.WIDGET_HELP_WATER_WORK, i, -1, False )
                fX += X_INCREMENT

        j = 0
        k = 0
        BugUtil.debug("CvTechChooser: Marker 27")
        # Improvements
        for j in range(gc.getNumBuildInfos()):
            bTechFound = False;

            if (gc.getBuildInfo(j).getTechPrereq() == -1):
                bTechFound = False
                for k in range(gc.getNumFeatureInfos()):
                    if (gc.getBuildInfo(j).getFeatureTech(k) == i):
                        bTechFound = True
            else:
                if (gc.getBuildInfo(j).getTechPrereq() == i):
                    bTechFound = True

            if (bTechFound):
                iCount += 1
                if (iCount < 10):
                    szImprovementButton = self.getNextWidgetName("Improvement")
                    screen.addDDSGFCAt( szImprovementButton, szTechRecord, gc.getBuildInfo(j).getButton(), iX + fX, iY + Y_ROW, TEXTURE_SIZE, TEXTURE_SIZE, WidgetTypes.WIDGET_HELP_IMPROVEMENT, i, j, False )
                    fX += X_INCREMENT
                   
                   
        j = 0
        k = 0

        BugUtil.debug("CvTechChooser: Marker 28")      
        # Improvements Can Upgrade
        for j in range(gc.getNumImprovementInfos()):
            if (gc.getImprovementInfo(j).getPrereqTech() == i):
                if (gc.getImprovementInfo(j).getImprovementPillage() != -1):
                    iCount += 1
                    if (iCount < 10):
                        szImprovementButton = self.getNextWidgetName("Improvement")
                        screen.addDDSGFCAt( szImprovementButton, szTechRecord, gc.getImprovementInfo(j).getButton(), iX + fX, iY + Y_ROW, TEXTURE_SIZE, TEXTURE_SIZE, WidgetTypes.WIDGET_HELP_IMPROVEMENT_CAN_UPGRADE, j, j, False )
                        fX += X_INCREMENT

        j = 0
        k = 0
        BugUtil.debug("CvTechChooser: Marker 29")
        # Domain Extra Moves
        for j in range( DomainTypes.NUM_DOMAIN_TYPES ):
            if (gc.getTechInfo(i).getDomainExtraMoves(j) != 0):
                iCount += 1
                if (iCount < 10):
                    szDomainExtraMovesButton = self.getNextWidgetName("DomainExtraMoves")
                    screen.addDDSGFCAt( szDomainExtraMovesButton, szTechRecord, ArtFileMgr.getInterfaceArtInfo("INTERFACE_TECH_WATERMOVES").getPath(), iX + fX, iY + Y_ROW, TEXTURE_SIZE, TEXTURE_SIZE, WidgetTypes.WIDGET_HELP_DOMAIN_EXTRA_MOVES, i, j, False )
                    fX += X_INCREMENT

        j = 0
        k = 0
        BugUtil.debug("CvTechChooser: Marker 30")
        # Adjustments
        for j in range( CommerceTypes.NUM_COMMERCE_TYPES ):
            if (gc.getTechInfo(i).isCommerceFlexible(j) and not (gc.getTeam(gc.getPlayer(self.iCivSelected).getTeam()).isCommerceFlexible(j))):
                szAdjustButton = self.getNextWidgetName("AdjustButton")
                if ( j == CommerceTypes.COMMERCE_CULTURE ):
                    szFileName = ArtFileMgr.getInterfaceArtInfo("INTERFACE_TECH_CULTURE").getPath()
                elif ( j == CommerceTypes.COMMERCE_ESPIONAGE ):
                    szFileName = ArtFileMgr.getInterfaceArtInfo("INTERFACE_TECH_ESPIONAGE").getPath()
                else:
                    szFileName = ArtFileMgr.getInterfaceArtInfo("INTERFACE_GENERAL_QUESTIONMARK").getPath()
                iCount += 1
                if (iCount < 10):
                    screen.addDDSGFCAt( szAdjustButton, szTechRecord, szFileName, iX + fX, iY + Y_ROW, TEXTURE_SIZE, TEXTURE_SIZE, WidgetTypes.WIDGET_HELP_ADJUST, i, j, False )
                    fX += X_INCREMENT

        j = 0
        k = 0
        BugUtil.debug("CvTechChooser: Marker 31")
        # Terrain opens up as a trade route
        for j in range( gc.getNumTerrainInfos() ):
            if (gc.getTechInfo(i).isTerrainTrade(j) and not (gc.getTeam(gc.getPlayer(self.iCivSelected).getTeam()).isTerrainTrade(j))):
                iCount += 1
                if (iCount < 10):
                    szTerrainTradeButton = self.getNextWidgetName("TerrainTradeButton")
                    screen.addDDSGFCAt( szTerrainTradeButton, szTechRecord, ArtFileMgr.getInterfaceArtInfo("INTERFACE_TECH_WATERTRADE").getPath(), iX + fX, iY + Y_ROW, TEXTURE_SIZE, TEXTURE_SIZE, WidgetTypes.WIDGET_HELP_TERRAIN_TRADE, i, j, False )
                    fX += X_INCREMENT

        j = gc.getNumTerrainInfos()  
        if (gc.getTechInfo(i).isRiverTrade() and not (gc.getTeam(gc.getPlayer(self.iCivSelected).getTeam()).isRiverTrade())):
            szTerrainTradeButton = self.getNextWidgetName("TerrainTradeButton")
            iCount += 1
            if (iCount < 10):
                screen.addDDSGFCAt( szTerrainTradeButton, szTechRecord, ArtFileMgr.getInterfaceArtInfo("INTERFACE_TECH_RIVERTRADE").getPath(), iX + fX, iY + Y_ROW, TEXTURE_SIZE, TEXTURE_SIZE, WidgetTypes.WIDGET_HELP_TERRAIN_TRADE, i, j, False )
                fX += X_INCREMENT

        j = 0
        k = 0
        BugUtil.debug("CvTechChooser: Marker 32")
        # Special buildings like monestaries...
        for j in range( gc.getNumSpecialBuildingInfos() ):
            if (gc.getSpecialBuildingInfo(j).getTechPrereq() == i):
                iCount += 1
                if (iCount < 10):
                    szSpecialBuilding = self.getNextWidgetName("SpecialBuildingButton")
                    screen.addDDSGFCAt( szSpecialBuilding, szTechRecord, gc.getSpecialBuildingInfo(j).getButton(), iX + fX, iY + Y_ROW, TEXTURE_SIZE, TEXTURE_SIZE, WidgetTypes.WIDGET_HELP_SPECIAL_BUILDING, i, j, False )
                    fX += X_INCREMENT

        j = 0
        k = 0
        BugUtil.debug("CvTechChooser: Marker 33")
        # Yield change
        for j in range( gc.getNumImprovementInfos() ):
            bFound = False
            for k in range( YieldTypes.NUM_YIELD_TYPES ):
                if (gc.getImprovementInfo(j).getTechYieldChanges(i, k)):
                    if ( bFound == False ):
                        iCount += 1
                        if (iCount < 10):
                            szYieldChange = self.getNextWidgetName("YieldChangeButton")
                            screen.addDDSGFCAt( szYieldChange, szTechRecord, gc.getImprovementInfo(j).getButton(), iX + fX, iY + Y_ROW, TEXTURE_SIZE, TEXTURE_SIZE, WidgetTypes.WIDGET_HELP_YIELD_CHANGE, i, j, False )
                            fX += X_INCREMENT
                            bFound = True

        j = 0
        k = 0
        BugUtil.debug("CvTechChooser: Marker 34")
        # Bonuses revealed
        for j in range( gc.getNumBonusInfos() ):
            if (gc.getBonusInfo(j).getTechReveal() == i):
                iCount += 1
                if (iCount < 10):
                    szBonusReveal = self.getNextWidgetName("BonusRevealButton")
                    screen.addDDSGFCAt( szBonusReveal, szTechRecord, gc.getBonusInfo(j).getButton(), iX + fX, iY + Y_ROW, TEXTURE_SIZE, TEXTURE_SIZE, WidgetTypes.WIDGET_HELP_BONUS_REVEAL, i, j, False )
                    fX += X_INCREMENT

        j = 0
        k = 0
        BugUtil.debug("CvTechChooser: Marker 35")
        # Civic options
        for j in range( gc.getNumCivicInfos() ):
            if (gc.getCivicInfo(j).getTechPrereq() == i):
                iCount += 1
                if (iCount < 10):
                    szCivicReveal = self.getNextWidgetName("CivicRevealButton")
                    screen.addDDSGFCAt( szCivicReveal, szTechRecord, gc.getCivicInfo(j).getButton(), iX + fX, iY + Y_ROW, TEXTURE_SIZE, TEXTURE_SIZE, WidgetTypes.WIDGET_HELP_CIVIC_REVEAL, i, j, False )
                    fX += X_INCREMENT

        j = 0
        k = 0
        BugUtil.debug("CvTechChooser: Marker 36")
        # Projects possible
        for j in range( gc.getNumProjectInfos() ):
            if (gc.getProjectInfo(j).getTechPrereq() == i):
                iCount += 1
                if (iCount < 10):
                    szProjectInfo = self.getNextWidgetName("ProjectInfoButton")
                    screen.addDDSGFCAt( szProjectInfo, szTechRecord, gc.getProjectInfo(j).getButton(), iX + fX, iY + Y_ROW, TEXTURE_SIZE, TEXTURE_SIZE, WidgetTypes.WIDGET_PEDIA_JUMP_TO_PROJECT, j, 1, False )
                    fX += X_INCREMENT

        j = 0
        k = 0
        BugUtil.debug("CvTechChooser: Marker 37")
        # Processes possible
        for j in range( gc.getNumProcessInfos() ):
            if (gc.getProcessInfo(j).getTechPrereq() == i):
                iCount += 1
                if (iCount < 10):
                    szProcessInfo = self.getNextWidgetName("ProcessInfoButton")
                    screen.addDDSGFCAt( szProcessInfo, szTechRecord, gc.getProcessInfo(j).getButton(), iX + fX, iY + Y_ROW, TEXTURE_SIZE, TEXTURE_SIZE, WidgetTypes.WIDGET_HELP_PROCESS_INFO, i, j, False )
                    fX += X_INCREMENT

        j = 0
        k = 0
        BugUtil.debug("CvTechChooser: Marker 38")
        # Religions unlocked
        for j in range( gc.getNumReligionInfos() ):
            if ( gc.getReligionInfo(j).getTechPrereq() == i ):
                szFoundReligion = self.getNextWidgetName("FoundReligionButton")
                if gc.getGame().isOption(GameOptionTypes.GAMEOPTION_PICK_RELIGION):
                    szButton = ArtFileMgr.getInterfaceArtInfo("INTERFACE_POPUPBUTTON_RELIGION").getPath()
                else:
                    szButton = gc.getReligionInfo(j).getButton()
                iCount += 1
                if (iCount < 10):
                    screen.addDDSGFCAt( szFoundReligion, szTechRecord, szButton, iX + fX, iY + Y_ROW, TEXTURE_SIZE, TEXTURE_SIZE, WidgetTypes.WIDGET_HELP_FOUND_RELIGION, i, j, False )
                    fX += X_INCREMENT
        BugUtil.debug("CvTechChooser: Marker 39")
        #Corporations Unlocked
        for j in range( gc.getNumCorporationInfos() ):
            if (gc.getGame().canEverSpread(j) ):
                if ( gc.getCorporationInfo(j).getTechPrereq() == i ):
                    iCount += 1
                    if (iCount < 10):
                        szFoundCorporation = self.getNextWidgetName("FoundCorporationButton")
                        screen.addDDSGFCAt( szFoundCorporation, szTechRecord, gc.getCorporationInfo(j).getButton(), iX + fX, iY + Y_ROW, TEXTURE_SIZE, TEXTURE_SIZE, WidgetTypes.WIDGET_HELP_FOUND_CORPORATION, i, j, False )
                        fX += X_INCREMENT
                elif (gc.getCorporationInfo(j).getObsoleteTech() == i):
                    iCount += 1
                    if (iCount < 10):
                        szCorporation = self.getNextWidgetName("FoundCorporationButton")
                        szObsoleteX = self.getNextWidgetName("ObsoleteX")
                        screen.addDDSGFCAt( szCorporation, szTechRecord, gc.getCorporationInfo(j).getButton(), iX + fX, iY + Y_ROW, TEXTURE_SIZE, TEXTURE_SIZE, WidgetTypes.WIDGET_OBSOLETE_CORPORATION, i, j, False )
                        screen.addDDSGFCAt( szObsoleteX, szTechRecord, ArtFileMgr.getInterfaceArtInfo("INTERFACE_BUTTONS_RED_X").getPath(), iX + fX, iY + Y_ROW, TEXTURE_SIZE, TEXTURE_SIZE, WidgetTypes.WIDGET_OBSOLETE_CORPORATION, j, -1, False )
           

    # Will update the tech records based on color, researching, researched, queued, etc.
    def updateTechRecords (self, bForce):
#        BugUtil.debug("cvTechChooser: updateTechRecords")

        # If we are the Pitboss, we don't want to put up an interface at all
        if ( CyGame().isPitbossHost() ):
            return

        if (self.sTechTabID == self.sTechSelectTab):
            bTechName = True
            sPanel = self.TabPanels[0]
# Rise of Mankind 2.7
            self.BOX_INCREMENT_WIDTH = 24 # Used to be 33 #Should be a multiple of 3...
# Rise of Mankind 2.7
        else:
            bTechName = False
            sPanel = self.TabPanels[1]
            self.BOX_INCREMENT_WIDTH = 12 # Used to be 33 #Should be a multiple of 3...

        # Get the screen
        screen = self.getScreen()

        abChanged = []
        bAnyChanged = 0

        # Go through all the techs
        for i in range(gc.getNumTechInfos()):

            abChanged.append(0)
           
            if (not gc.getPlayer(0).canEverResearch(i)): continue

            if ( gc.getTeam(gc.getPlayer(self.iCivSelected).getTeam()).isHasTech(i) ):
                if ( self.aiCurrentState[i] != CIV_HAS_TECH ):
                    self.aiCurrentState[i] = CIV_HAS_TECH
                    abChanged[i] = 1
                    bAnyChanged = 1
            elif ( gc.getPlayer(self.iCivSelected).getCurrentResearch() == i ):
                if ( self.aiCurrentState[i] != CIV_IS_RESEARCHING ):
                    self.aiCurrentState[i] = CIV_IS_RESEARCHING
                    abChanged[i] = 1
                    bAnyChanged = 1
            elif ( gc.getPlayer(self.iCivSelected).isResearchingTech(i) ):
                if ( self.aiCurrentState[i] != CIV_IS_RESEARCHING ):
                    self.aiCurrentState[i] = CIV_IS_RESEARCHING
                    abChanged[i] = 1
                    bAnyChanged = 1
            elif ( gc.getPlayer(self.iCivSelected).canEverResearch(i) ):
                if ( self.aiCurrentState[i] != CIV_NO_RESEARCH ):
                    self.aiCurrentState[i] = CIV_NO_RESEARCH
                    abChanged[i] = 1
                    bAnyChanged = 1
            else:
                if ( self.aiCurrentState[i] != CIV_TECH_AVAILABLE ):
                    self.aiCurrentState[i] = CIV_TECH_AVAILABLE
                    abChanged[i] = 1
                    bAnyChanged = 1

        for i in range(gc.getNumTechInfos()):
            if (abChanged[i] or bForce or (bAnyChanged and gc.getPlayer(self.iCivSelected).isResearchingTech(i))):
                # Create and place a tech in its proper location
                szTechRecord = "TechRecord" + str(i)
                szTechID = "TechID" + str(i)
                szTechString = "<font=1>"

                if ( gc.getPlayer(self.iCivSelected).isResearchingTech(i) ):
                    szTechString = szTechString + unicode(gc.getPlayer(self.iCivSelected).getQueuePosition(i)) + ". "

                iX = 30 + ( (gc.getTechInfo(i).getGridX() - 1) * ( ( self.BOX_INCREMENT_X_SPACING + self.BOX_INCREMENT_WIDTH ) * self.PIXEL_INCREMENT ) )
# Rise of Mankind 2.7 - more techs vertically
                iY = ( gc.getTechInfo(i).getGridY() - 1 ) * ( self.BOX_INCREMENT_Y_SPACING * self.PIXEL_INCREMENT )
# Rise of Mankind 2.7 - more techs vertically
                if bTechName:
                    szTechString += gc.getTechInfo(i).getDescription()
                    if ( gc.getPlayer(self.iCivSelected).isResearchingTech(i) ):
                        szTechString += " ("
                        szTechString += str(gc.getPlayer(self.iCivSelected).getResearchTurnsLeft(i, ( gc.getPlayer(self.iCivSelected).getCurrentResearch() == i )))
                        szTechString += ")"
                    szTechString = szTechString + "</font>"
                    screen.setTextAt( szTechID, sPanel, szTechString, CvUtil.FONT_LEFT_JUSTIFY, iX + 6 + X_INCREMENT, iY + 6, -0.1, FontTypes.SMALL_FONT, WidgetTypes.WIDGET_TECH_TREE, i, -1 )
                    screen.setActivation( szTechID, ActivationTypes.ACTIVATE_MIMICPARENTFOCUS )

                if ( gc.getTeam(gc.getPlayer(self.iCivSelected).getTeam()).isHasTech(i) ):
                    screen.setPanelColor(szTechRecord, 0, 0, 0)
                elif ( gc.getPlayer(self.iCivSelected).getCurrentResearch() == i ):
                    screen.setPanelColor(szTechRecord, 0, 0, 200)
                elif ( gc.getPlayer(self.iCivSelected).isResearchingTech(i) ):
                    screen.setPanelColor(szTechRecord, 200, 0, 0)
                elif ( gc.getPlayer(self.iCivSelected).canEverResearch(i) ):
# Rise of Mankind 2.91 - tech tree colors - start
                    if (RoMOpt.isRoMTechTreeColors()):
                        # Ancient Era
                        if ( gc.getTechInfo(i).getEra() == 0 ):
                            screen.setPanelColor(szTechRecord, 160, 100, 160)
                        # Classical Era
                        elif ( gc.getTechInfo(i).getEra() == 1 ):
                            screen.setPanelColor(szTechRecord, 160, 100, 100)
                        # Medieval Era
                        elif ( gc.getTechInfo(i).getEra() == 2 ):
                            screen.setPanelColor(szTechRecord, 160, 160, 100)
                        # Renaissance Era
                        elif ( gc.getTechInfo(i).getEra() == 3 ):
                            screen.setPanelColor(szTechRecord, 160, 160, 50)
                        # Industrial Era
                        elif ( gc.getTechInfo(i).getEra() == 4 ):
                            screen.setPanelColor(szTechRecord, 60, 200, 60)
                        # Modern Era
                        elif ( gc.getTechInfo(i).getEra() == 5 ):
                            screen.setPanelColor(szTechRecord, 100, 104, 160)
                        # Future Era
                        else:
                            screen.setPanelColor(szTechRecord, 50, 160, 250)
                            #screen.setPanelColor(szTechRecord, 0, 160, 160)
                    else:
                        screen.setPanelColor(szTechRecord, 100, 104, 160)
# Rise of Mankind 2.91 - tech tree colors - end
                else:
                    screen.setPanelColor(szTechRecord, 206, 65, 69)

# BUG - GP Tech Prefs - start
        self.updateTechPrefs()
# BUG - GP Tech Prefs - end

# BUG - Tech Era Colors - start
    def setTechPanelShadowColor(self, screen, sPanel, iEra):
        szEra = gc.getEraInfo(iEra).getType()
        iColor = ClockOpt.getEraColor(szEra)
        if iColor != -1:
            color = gc.getColorInfo(iColor)
            if color:
                rgb = color.getColor() # NiColorA object
                if rgb:
                    screen.setPanelColor(sPanel, int(100 * rgb.r), int(100 * rgb.g), int(100 * rgb.b))
# BUG - Tech Era Colors - end

    # Will draw the arrows
    def drawArrows(self, screen, sPanel, bANDPreReq, bORPreReq):
#        BugUtil.debug("cvTechChooser: drawArrows")

        iLoop = 0

        ARROW_X = ArtFileMgr.getInterfaceArtInfo("ARROW_X").getPath()
        ARROW_Y = ArtFileMgr.getInterfaceArtInfo("ARROW_Y").getPath()
        ARROW_MXMY = ArtFileMgr.getInterfaceArtInfo("ARROW_MXMY").getPath()
        ARROW_XY = ArtFileMgr.getInterfaceArtInfo("ARROW_XY").getPath()
        ARROW_MXY = ArtFileMgr.getInterfaceArtInfo("ARROW_MXY").getPath()
        ARROW_XMY = ArtFileMgr.getInterfaceArtInfo("ARROW_XMY").getPath()
        ARROW_HEAD = ArtFileMgr.getInterfaceArtInfo("ARROW_HEAD").getPath()

        for i in range(gc.getNumTechInfos()):
            bFirst = 1
            fX = (self.BOX_INCREMENT_WIDTH * self.PIXEL_INCREMENT) - 8
            if (not gc.getPlayer(0).canEverResearch(i)) : continue
            if bANDPreReq:
                numTechOverrides = gc.getTechInfo(i).getNumTechArrowOverrides()
                for j in range( gc.getNUM_AND_TECH_PREREQS() ):
                    eTech = gc.getTechInfo(i).getPrereqAndTechs(j)
                    if (numTechOverrides > 0):
                        for k in range (numTechOverrides):
                            fTech = gc.getTechInfo(i).getTechArrowOverride(k)
                            if ( eTech > -1 and eTech != fTech):
                                fX = fX - X_INCREMENT
                                iX = 30 + ( (gc.getTechInfo(i).getGridX() - 1) * ( ( self.BOX_INCREMENT_X_SPACING + self.BOX_INCREMENT_WIDTH ) * self.PIXEL_INCREMENT ) )
# Rise of Mankind 2.7 - more techs vertically
#                                iY = ( gc.getTechInfo(i).getGridY() - 1 ) * ( self.BOX_INCREMENT_Y_SPACING * self.PIXEL_INCREMENT ) + 5
                                iY = ( gc.getTechInfo(i).getGridY() - 1 ) * ( self.BOX_INCREMENT_Y_SPACING * self.PIXEL_INCREMENT )
# Rise of Mankind 2.7 - more techs vertically
                                szTechPrereqID = "TechPrereqID" + str((i * 1000) + j)
                                screen.addDDSGFCAt( szTechPrereqID, sPanel, gc.getTechInfo(eTech).getButton(), iX + fX, iY + 6, TEXTURE_SIZE, TEXTURE_SIZE, WidgetTypes.WIDGET_HELP_TECH_PREPREQ, eTech, -1, False )
                                #szTechPrereqBorderID = "TechPrereqBorderID" + str((i * 1000) + j)
                                #screen.addDDSGFCAt( szTechPrereqBorderID, sPanel, ArtFileMgr.getInterfaceArtInfo("TECH_TREE_BUTTON_BORDER").getPath(), iX + fX + 4, iY + 22, 32, 32, WidgetTypes.WIDGET_HELP_TECH_PREPREQ, eTech, -1, False )
                    else:
                        if ( eTech > -1):
                            fX = fX - X_INCREMENT
                            iX = 30 + ( (gc.getTechInfo(i).getGridX() - 1) * ( ( self.BOX_INCREMENT_X_SPACING + self.BOX_INCREMENT_WIDTH ) * self.PIXEL_INCREMENT ) )
# Rise of Mankind 2.7 - more techs vertically
#                            iY = ( gc.getTechInfo(i).getGridY() - 1 ) * ( self.BOX_INCREMENT_Y_SPACING * self.PIXEL_INCREMENT ) + 5
                            iY = ( gc.getTechInfo(i).getGridY() - 1 ) * ( self.BOX_INCREMENT_Y_SPACING * self.PIXEL_INCREMENT )
# Rise of Mankind 2.7 - more techs vertically
                            szTechPrereqID = "TechPrereqID" + str((i * 1000) + j)
                            screen.addDDSGFCAt( szTechPrereqID, sPanel, gc.getTechInfo(eTech).getButton(), iX + fX, iY + 6, TEXTURE_SIZE, TEXTURE_SIZE, WidgetTypes.WIDGET_HELP_TECH_PREPREQ, eTech, -1, False )
                            #szTechPrereqBorderID = "TechPrereqBorderID" + str((i * 1000) + j)
                            #screen.addDDSGFCAt( szTechPrereqBorderID, sPanel, ArtFileMgr.getInterfaceArtInfo("TECH_TREE_BUTTON_BORDER").getPath(), iX + fX + 4, iY + 22, 32, 32, WidgetTypes.WIDGET_HELP_TECH_PREPREQ, eTech, -1, False )


            j = 0

            if bORPreReq:
                numTechOverrides = gc.getTechInfo(i).getNumTechArrowOverrides()
                BugUtil.info("CvTechChooser: Num Tech Overrides for " + gc.getTechInfo(i).getDescription() + " is " + str(numTechOverrides))
                for j in range( max(gc.getNUM_OR_TECH_PREREQS(), numTechOverrides) ):
                    if (numTechOverrides > 0):
                        if (j >= numTechOverrides):
                            eTech = -1
                        else:
                            eTech = gc.getTechInfo(i).getTechArrowOverride(j)
                            BugUtil.info("CvTechChooser: Tech Overrides for " + gc.getTechInfo(i).getDescription() + " is " + gc.getTechInfo(eTech).getDescription())
                    else:
                        eTech = gc.getTechInfo(i).getPrereqOrTechs(j)
                       
                    if ( eTech > -1 ):
                        iX = 24 + ( (gc.getTechInfo(eTech).getGridX() - 1) * ( ( self.BOX_INCREMENT_X_SPACING + self.BOX_INCREMENT_WIDTH ) * self.PIXEL_INCREMENT ) )
                        iY = ( gc.getTechInfo(eTech).getGridY() - 1 ) * ( self.BOX_INCREMENT_Y_SPACING * self.PIXEL_INCREMENT ) + 5

                        # j is the pre-req, i is the tech...
                        xDiff = gc.getTechInfo(i).getGridX() - gc.getTechInfo(eTech).getGridX()
                        yDiff = gc.getTechInfo(i).getGridY() - gc.getTechInfo(eTech).getGridY()

# Rise of Mankind - more techs vertically
                        if (yDiff == 0):
                            screen.addDDSGFCAt( self.getNextWidgetName("TechArrow"), sPanel, ARROW_X, iX + self.getXStart(), iY + self.getYStart(3) + 1, self.getWidth(xDiff), 8, WidgetTypes.WIDGET_GENERAL, -1, -1, False )
                            screen.addDDSGFCAt( self.getNextWidgetName("TechArrow"), sPanel, ARROW_HEAD, iX + self.getXStart() + self.getWidth(xDiff), iY + self.getYStart(3) + 1, 8, 8, WidgetTypes.WIDGET_GENERAL, -1, -1, False )
                        elif (yDiff < 0):
                            if ( yDiff == -6 ):
                                screen.addDDSGFCAt( self.getNextWidgetName("TechArrow"), sPanel, ARROW_X, iX + self.getXStart(), iY + self.getYStart(1) + 10, self.getWidth(xDiff) / 2, 8, WidgetTypes.WIDGET_GENERAL, -1, -1, False )
                                screen.addDDSGFCAt( self.getNextWidgetName("TechArrow"), sPanel, ARROW_XY, iX + self.getXStart() + ( self.getWidth(xDiff) / 2 ), iY + self.getYStart(1) + 10, 8, 8, WidgetTypes.WIDGET_GENERAL, -1, -1, False )
                                screen.addDDSGFCAt( self.getNextWidgetName("TechArrow"), sPanel, ARROW_Y, iX + self.getXStart() + ( self.getWidth(xDiff) / 2 ), iY + self.getYStart(1) + 8 - self.getHeight(yDiff, 0) + 125, 8, self.getHeight(yDiff, 0) - 8 - 115, WidgetTypes.WIDGET_GENERAL, -1, -1, False )
                                screen.addDDSGFCAt( self.getNextWidgetName("TechArrow"), sPanel, ARROW_XMY, iX + self.getXStart() + ( self.getWidth(xDiff) / 2 ), iY + self.getYStart(1) - self.getHeight(yDiff, 0) + 125, 8, 8, WidgetTypes.WIDGET_GENERAL, -1, -1, False )
                                screen.addDDSGFCAt( self.getNextWidgetName("TechArrow"), sPanel, ARROW_X, iX + 8 + self.getXStart() + ( self.getWidth(xDiff) / 2 ), iY + self.getYStart(1) - self.getHeight(yDiff, 0) + 125, ( self.getWidth(xDiff) / 2 ) - 8, 8, WidgetTypes.WIDGET_GENERAL, -1, -1, False )
                                screen.addDDSGFCAt( self.getNextWidgetName("TechArrow"), sPanel, ARROW_HEAD, iX + self.getXStart() + self.getWidth(xDiff), iY + self.getYStart(1) - self.getHeight(yDiff, 0) + 125, 8, 8, WidgetTypes.WIDGET_GENERAL, -1, -1, False )
                            elif ( yDiff == -2 and xDiff == 2 ):
                                screen.addDDSGFCAt( self.getNextWidgetName("TechArrow"), sPanel, ARROW_X, iX + self.getXStart(), iY + self.getYStart(2) + 10, self.getWidth(xDiff) * 5 / 6, 8, WidgetTypes.WIDGET_GENERAL, -1, -1, False )
                                screen.addDDSGFCAt( self.getNextWidgetName("TechArrow"), sPanel, ARROW_XY, iX + self.getXStart() + ( self.getWidth(xDiff) * 5 / 6 ), iY + self.getYStart(2) + 10, 8, 8, WidgetTypes.WIDGET_GENERAL, -1, -1, False )
                                screen.addDDSGFCAt( self.getNextWidgetName("TechArrow"), sPanel, ARROW_Y, iX + self.getXStart() + ( self.getWidth(xDiff) * 5 / 6 ), iY + self.getYStart(2) + 8 - ( self.getHeight(yDiff, 3) / 2 ) + 15, 8, ( self.getHeight(yDiff, 3) / 2 ) - 8 - 5, WidgetTypes.WIDGET_GENERAL, -1, -1, False )
                                screen.addDDSGFCAt( self.getNextWidgetName("TechArrow"), sPanel, ARROW_XMY, iX + self.getXStart() + ( self.getWidth(xDiff) * 5 / 6 ), iY + self.getYStart(2) - ( self.getHeight(yDiff, 3) / 2 ) + 15, 8, 8, WidgetTypes.WIDGET_GENERAL, -1, -1, False )
                                screen.addDDSGFCAt( self.getNextWidgetName("TechArrow"), sPanel, ARROW_X, iX + 8 + self.getXStart() + ( self.getWidth(xDiff) * 5 / 6 ), iY + self.getYStart(2) - ( self.getHeight(yDiff, 3) / 2 ) + 15, ( self.getWidth(xDiff) / 6 ) - 8, 8, WidgetTypes.WIDGET_GENERAL, -1, -1, False )
                                screen.addDDSGFCAt( self.getNextWidgetName("TechArrow"), sPanel, ARROW_HEAD, iX + self.getXStart() + self.getWidth(xDiff), iY + self.getYStart(2) - ( self.getHeight(yDiff, 3) / 2 ) + 15, 8, 8, WidgetTypes.WIDGET_GENERAL, -1, -1, False )
                            else:
                                screen.addDDSGFCAt( self.getNextWidgetName("TechArrow"), sPanel, ARROW_X, iX + self.getXStart(), iY + self.getYStart(2) - 5, self.getWidth(xDiff) / 2, 8, WidgetTypes.WIDGET_GENERAL, -1, -1, False )
                                screen.addDDSGFCAt( self.getNextWidgetName("TechArrow"), sPanel, ARROW_XY, iX + self.getXStart() + ( self.getWidth(xDiff) / 2 ), iY + self.getYStart(2) - 5, 8, 8, WidgetTypes.WIDGET_GENERAL, -1, -1, False )
                                screen.addDDSGFCAt( self.getNextWidgetName("TechArrow"), sPanel, ARROW_Y, iX + self.getXStart() + ( self.getWidth(xDiff) / 2 ), iY + ( self.getYStart(2) / 2 ) + 8 - ( self.getHeight(yDiff, 3) / 2 ) + 10, 8, ( self.getHeight(yDiff, 3) / 2 ) - 8 - 10, WidgetTypes.WIDGET_GENERAL, -1, -1, False )
                                screen.addDDSGFCAt( self.getNextWidgetName("TechArrow"), sPanel, ARROW_XMY, iX + self.getXStart() + ( self.getWidth(xDiff) / 2 ), iY + ( self.getYStart(2) / 2 ) - ( self.getHeight(yDiff, 3) / 2 ) + 10, 8, 8, WidgetTypes.WIDGET_GENERAL, -1, -1, False )
                                screen.addDDSGFCAt( self.getNextWidgetName("TechArrow"), sPanel, ARROW_X, iX + 8 + self.getXStart() + ( self.getWidth(xDiff) / 2 ), iY + ( self.getYStart(2) / 2 ) - ( self.getHeight(yDiff, 3) / 2 ) + 10, ( self.getWidth(xDiff) / 2 ) - 8, 8, WidgetTypes.WIDGET_GENERAL, -1, -1, False )
                                screen.addDDSGFCAt( self.getNextWidgetName("TechArrow"), sPanel, ARROW_HEAD, iX + self.getXStart() + self.getWidth(xDiff), iY + ( self.getYStart(2) / 2 ) - ( self.getHeight(yDiff, 3) / 2 ) + 10, 8, 8, WidgetTypes.WIDGET_GENERAL, -1, -1, False )
                        elif (yDiff > 0):
                            if ( yDiff == 2 and xDiff == 2):
                                screen.addDDSGFCAt( self.getNextWidgetName("TechArrow"), sPanel, ARROW_X, iX + self.getXStart(), iY + self.getYStart(4) * 2 - 15, self.getWidth(xDiff) / 6, 8, WidgetTypes.WIDGET_GENERAL, -1, -1, False )
                                screen.addDDSGFCAt( self.getNextWidgetName("TechArrow"), sPanel, ARROW_MXMY, iX + self.getXStart() + ( self.getWidth(xDiff) / 6 ), iY + self.getYStart(4) * 2 - 15, 8, 8, WidgetTypes.WIDGET_GENERAL, -1, -1, False )
                                screen.addDDSGFCAt( self.getNextWidgetName("TechArrow"), sPanel, ARROW_Y, iX + self.getXStart() + ( self.getWidth(xDiff) / 6 ), iY + self.getYStart(4) * 2 + 8 - 15, 8, ( self.getHeight(yDiff, 3) / 2 ) - 8 - 30, WidgetTypes.WIDGET_GENERAL, -1, -1, False )
                                screen.addDDSGFCAt( self.getNextWidgetName("TechArrow"), sPanel, ARROW_MXY, iX + self.getXStart() + ( self.getWidth(xDiff) / 6 ), iY + self.getYStart(4) / 2 + ( self.getHeight(yDiff, 3) / 2 ), 8, 8, WidgetTypes.WIDGET_GENERAL, -1, -1, False )
                                screen.addDDSGFCAt( self.getNextWidgetName("TechArrow"), sPanel, ARROW_X, iX + 8 + self.getXStart() + ( self.getWidth(xDiff) / 6 ), iY + self.getYStart(4) / 2 + ( self.getHeight(yDiff, 3) / 2 ), ( self.getWidth(xDiff) * 5 / 6 ) - 8, 8, WidgetTypes.WIDGET_GENERAL, -1, -1, False )
                                screen.addDDSGFCAt( self.getNextWidgetName("TechArrow"), sPanel, ARROW_HEAD, iX + self.getXStart() + self.getWidth(xDiff), iY + self.getYStart(4) / 2 + ( self.getHeight(yDiff, 3) / 2 ), 8, 8, WidgetTypes.WIDGET_GENERAL, -1, -1, False )
                            elif ( yDiff == 4 and xDiff == 1):
                                screen.addDDSGFCAt( self.getNextWidgetName("TechArrow"), sPanel, ARROW_X, iX + self.getXStart(), iY + self.getYStart(5), self.getWidth(xDiff) / 3, 8, WidgetTypes.WIDGET_GENERAL, -1, -1, False )
                                screen.addDDSGFCAt( self.getNextWidgetName("TechArrow"), sPanel, ARROW_MXMY, iX + self.getXStart() + ( self.getWidth(xDiff) / 3 ), iY + self.getYStart(5), 8, 8, WidgetTypes.WIDGET_GENERAL, -1, -1, False )
                                screen.addDDSGFCAt( self.getNextWidgetName("TechArrow"), sPanel, ARROW_Y, iX + self.getXStart() + ( self.getWidth(xDiff) / 3 ), iY + self.getYStart(5) + 8, 8, self.getHeight(yDiff, 0) - 8 - 95, WidgetTypes.WIDGET_GENERAL, -1, -1, False )
                                screen.addDDSGFCAt( self.getNextWidgetName("TechArrow"), sPanel, ARROW_MXY, iX + self.getXStart() + ( self.getWidth(xDiff) / 3 ), iY + self.getYStart(5) + self.getHeight(yDiff, 0) - 100, 8, 8, WidgetTypes.WIDGET_GENERAL, -1, -1, False )
                                screen.addDDSGFCAt( self.getNextWidgetName("TechArrow"), sPanel, ARROW_X, iX + 8 + self.getXStart() + ( self.getWidth(xDiff) / 3 ), iY + self.getYStart(5) + self.getHeight(yDiff, 0) - 100, ( self.getWidth(xDiff) * 2 / 3 ) - 8, 8, WidgetTypes.WIDGET_GENERAL, -1, -1, False )
                                screen.addDDSGFCAt( self.getNextWidgetName("TechArrow"), sPanel, ARROW_HEAD, iX + self.getXStart() + self.getWidth(xDiff), iY + self.getYStart(5) + self.getHeight(yDiff, 0) - 100, 8, 8, WidgetTypes.WIDGET_GENERAL, -1, -1, False )
                            else:
                                screen.addDDSGFCAt( self.getNextWidgetName("TechArrow"), sPanel, ARROW_X, iX + self.getXStart(), iY + self.getYStart(4) + 5, self.getWidth(xDiff) / 2, 8, WidgetTypes.WIDGET_GENERAL, -1, -1, False )
                                screen.addDDSGFCAt( self.getNextWidgetName("TechArrow"), sPanel, ARROW_MXMY, iX + self.getXStart() + ( self.getWidth(xDiff) / 2 ), iY + self.getYStart(4) + 5, 8, 8, WidgetTypes.WIDGET_GENERAL, -1, -1, False )
                                screen.addDDSGFCAt( self.getNextWidgetName("TechArrow"), sPanel, ARROW_Y, iX + self.getXStart() + ( self.getWidth(xDiff) / 2 ), iY + self.getYStart(4) + 8 + 5, 8, ( self.getHeight(yDiff, 3) / 2 ) - 8, WidgetTypes.WIDGET_GENERAL, -1, -1, False )
                                screen.addDDSGFCAt( self.getNextWidgetName("TechArrow"), sPanel, ARROW_MXY, iX + self.getXStart() + ( self.getWidth(xDiff) / 2 ), iY + self.getYStart(4) + (self.getHeight(yDiff, 3) / 2 ), 8, 8, WidgetTypes.WIDGET_GENERAL, -1, -1, False )
                                screen.addDDSGFCAt( self.getNextWidgetName("TechArrow"), sPanel, ARROW_X, iX + 8 + self.getXStart() + ( self.getWidth(xDiff) / 2 ), iY + self.getYStart(4) + (self.getHeight(yDiff, 3) / 2 ), ( self.getWidth(xDiff) / 2 ) - 8, 8, WidgetTypes.WIDGET_GENERAL, -1, -1, False )
                                screen.addDDSGFCAt( self.getNextWidgetName("TechArrow"), sPanel, ARROW_HEAD, iX + self.getXStart() + self.getWidth(xDiff), iY + self.getYStart(4) + (self.getHeight(yDiff, 3) / 2 ), 8, 8, WidgetTypes.WIDGET_GENERAL, -1, -1, False )

# Rise of Mankind 2.7 - more techs vertically

        return

# BUG - GP Tech Prefs - start
    def resetTechPrefs (self):
        self.pPrefs = TechPrefs.TechPrefs()
   
    def updateTechPrefs (self):
#        BugUtil.debug("cvTechChooser: updateTechPrefs")

        # If we are the Pitboss, we don't want to put up an interface at all
        if ( CyGame().isPitbossHost() ):
            return

        # These don't seem to be setup when screen is first opened
        if (gc.getNumTechInfos() <= 0 or gc.getNumFlavorTypes() <= 0):
            return

        # Get the screen and player
        screen = self.getScreen()
        pPlayer = gc.getPlayer(self.iCivSelected)

        # Don't show tech prefs during advanced start setup
        if (pPlayer.getAdvancedStartPoints() >= 0):
            return

        # Check to see if option is disabled
        if (not BugOpt.isShowGPTechPrefs()):
            if (self.bPrefsShowing):
                # ... and if so, remove icons if they are currently showing
                screen.hide( "GreatPersonHeading")
                for i, f in enumerate(FLAVORS):
                    screen.hide( "GreatPerson" + str(f) )
                    screen.hide( "GreatPersonTech" + str(f) )
                    screen.hide( "GreatPersonTechNext" + str(f) )
                self.bPrefsShowing = False
            return
        # Always redraw the GP icons because otherwise they are prone to disappearing
        # discover icon heading
        iIconSize = 48
        iX = PREF_ICON_LEFT + 5 * PREF_ICON_SIZE / 4 - iIconSize / 2
        iY = PREF_ICON_TOP - iIconSize - 40
        screen.addDDSGFC( "GreatPersonHeading", ArtFileMgr.getInterfaceArtInfo("DISCOVER_TECHNOLOGY_BUTTON").getPath(), iX, iY, iIconSize, iIconSize, WidgetTypes.WIDGET_GENERAL, -1, -1 )

        for i, f in enumerate(FLAVORS):
            # GP icon
            iUnitClass = gc.getInfoTypeForString(UNIT_CLASSES[i])
            iUnitType = gc.getUnitClassInfo(iUnitClass).getDefaultUnitIndex()
            pUnitInfo = gc.getUnitInfo(iUnitType)
            iX = PREF_ICON_LEFT
            iY = PREF_ICON_TOP + 4 * i * PREF_ICON_SIZE
            screen.addDDSGFC( "GreatPerson" + str(f), pUnitInfo.getButton(), iX, iY, PREF_ICON_SIZE, PREF_ICON_SIZE, WidgetTypes.WIDGET_TECH_PREFS_ALL, f, -1 )
        self.bPrefsShowing = True

        # Remove any techs researched since last call, creating tree if necessary
        if (not self.pPrefs):
            self.resetTechPrefs()
        self.pPrefs.removeKnownTechs()

        # Add all techs in research queue to set of soon-to-be-known techs
        sTechs = set()
        for i in range(gc.getNumTechInfos()):
            if (pPlayer.isResearchingTech(i)):
                sTechs.add(self.pPrefs.getTech(i))

        # Update the buttons to reflect the new tech prefs
        for i, f in enumerate(FLAVORS):
            # GP button
            screen.show( "GreatPerson" + str(f) )

            # Current tech GP will pop
            szButtonName = "GreatPersonTech" + str(f)
            pTech = self.pPrefs.getNextResearchableFlavorTech(f)
            iX = PREF_ICON_LEFT + 3 * PREF_ICON_SIZE / 2
            iY = PREF_ICON_TOP + 4 * i * PREF_ICON_SIZE
            if (pTech):
                screen.addDDSGFC( szButtonName, pTech.getInfo().getButton(), iX, iY, PREF_ICON_SIZE, PREF_ICON_SIZE, WidgetTypes.WIDGET_TECH_PREFS_CURRENT, f, -1 )
            else:
                screen.addDDSGFC( szButtonName, self.NO_TECH_ART, iX, iY, PREF_ICON_SIZE, PREF_ICON_SIZE, WidgetTypes.WIDGET_TECH_PREFS_CURRENT, f, -1 )
            screen.show( szButtonName )

            # Tech GP will pop once selected techs are researched
            szButtonName = "GreatPersonTechNext" + str(f)
            pTech = self.pPrefs.getNextResearchableWithFlavorTech(f, sTechs)
            iX = PREF_ICON_LEFT + 3 * PREF_ICON_SIZE / 2
            iY = PREF_ICON_TOP + 4 * i * PREF_ICON_SIZE + 3 * PREF_ICON_SIZE / 2
            if (pTech):
                screen.addDDSGFC( szButtonName, pTech.getInfo().getButton(), iX, iY, PREF_ICON_SIZE, PREF_ICON_SIZE, WidgetTypes.WIDGET_TECH_PREFS_FUTURE, f, -1 )
            else:
                screen.addDDSGFC( szButtonName, self.NO_TECH_ART, iX, iY, PREF_ICON_SIZE, PREF_ICON_SIZE, WidgetTypes.WIDGET_TECH_PREFS_FUTURE, f, -1 )
            screen.show( szButtonName )
# BUG - GP Tech Prefs - end

    def TechRecord (self, inputClass):
        return 0

    # Clicked the parent?
    def ParentClick (self, inputClass):
        return 0

    def CivDropDown( self, inputClass ):
        if ( inputClass.getNotifyCode() == NotifyCode.NOTIFY_LISTBOX_ITEM_SELECTED ):
            screen = self.getScreen()
            iIndex = screen.getSelectedPullDownID("CivDropDown")
            self.iCivSelected = screen.getPullDownData("CivDropDown", iIndex)
            self.updateTechRecords(False)

    # Will handle the input for this screen...
    def handleInput (self, inputClass):
#        BugUtil.debug("cvTechChooser: handleInput")
#        BugUtil.debugInput(inputClass)

        # Get the screen
        screen = self.getScreen()

        szWidgetName = inputClass.getFunctionName() + str(inputClass.getID())

        # Advanced Start Stuff
        pPlayer = gc.getPlayer(self.iCivSelected)
        if (pPlayer.getAdvancedStartPoints() >= 0):
#            BugUtil.debug("cvTechChooser: handleInput - advancedstart")
            # Add tech button
            if (inputClass.getFunctionName() == "AddTechButton"):
                if (pPlayer.getAdvancedStartTechCost(self.m_iSelectedTech, True) != -1):
                    CyMessageControl().sendAdvancedStartAction(AdvancedStartActionTypes.ADVANCEDSTARTACTION_TECH, self.iCivSelected, -1, -1, self.m_iSelectedTech, True)    #Action, Player, X, Y, Data, bAdd
                    self.m_bTechRecordsDirty = True
                    self.m_bSelectedTechDirty = True

            # Tech clicked on
            elif (inputClass.getNotifyCode() == NotifyCode.NOTIFY_CLICKED):
                if (inputClass.getButtonType() == WidgetTypes.WIDGET_TECH_TREE):
                    self.m_iSelectedTech = inputClass.getData1()
                    self.updateSelectedTech()

        ' Calls function mapped in TechChooserInputMap'
        # only get from the map if it has the key
        if ( inputClass.getNotifyCode() == NotifyCode.NOTIFY_LISTBOX_ITEM_SELECTED ):
#            BugUtil.debug("cvTechChooser: handleInput - dropdown")
            self.CivDropDown( inputClass )
            return 1

        if (inputClass.getNotifyCode() == NotifyCode.NOTIFY_CLICKED):
            if szWidgetName == self.sTechSelectTab:
                self.sTechTabID = self.sTechSelectTab
                self.ShowTab()

            elif szWidgetName == self.sTechTradeTab:
                self.sTechTabID = self.sTechTradeTab
                self.ShowTab()



        return 0

    def getNextWidgetName(self, sName):
#        BugUtil.debug("cvTechChooser: getNextWidgetName %i %i", self.nWidgetCount, len(self.sWidgets))
        szName = sName + str(self.nWidgetCount)
        self.nWidgetCount += 1
        self.sWidgets.append(szName)
        return szName

    def deleteWidgets(self):
#        BugUtil.debug("cvTechChooser: deleteWidgets %i %i", self.nWidgetCount, len(self.sWidgets))
        screen = self.getScreen()
        for w in self.sWidgets:
#            BugUtil.debug("cvTechChooser: deleteWidgets '%s'", w)
            screen.deleteWidget(w)

        self.nWidgetCount = 0
        self.sWidgets = []
        return





    def getXStart(self):
        return ( self.BOX_INCREMENT_WIDTH * self.PIXEL_INCREMENT )

    def getXSpacing(self):
        return ( self.BOX_INCREMENT_X_SPACING * self.PIXEL_INCREMENT )

    def getYStart(self, iY):
        return int((((self.BOX_INCREMENT_HEIGHT * self.PIXEL_INCREMENT ) / 6.0) * iY) - self.PIXEL_INCREMENT )

    def getWidth(self, xDiff):
        return ( ( xDiff * self.getXSpacing() ) + ( ( xDiff - 1 ) * self.getXStart() ) )

    def getHeight(self, yDiff, nFactor):
        return ( ( nFactor + ( ( abs( yDiff ) - 1 ) * 6 ) ) * self.PIXEL_INCREMENT )

    def update(self, fDelta):
        if (CyInterface().isDirty(InterfaceDirtyBits.Advanced_Start_DIRTY_BIT)):
            CyInterface().setDirty(InterfaceDirtyBits.Advanced_Start_DIRTY_BIT, False)

            if (self.m_bSelectedTechDirty):
                self.m_bSelectedTechDirty = False
                self.updateSelectedTech()

            if (self.m_bTechRecordsDirty):
                self.m_bTechRecordsDirty = False
                self.updateTechRecords(True)

            if (gc.getPlayer(self.iCivSelected).getAdvancedStartPoints() < 0):
                # hide the screen
                screen = self.getScreen()
                screen.hide("AddTechButton")
                screen.hide("ASPointsLabel")
                screen.hide("SelectedTechLabel")

        return

    def updateSelectedTech(self):
        pPlayer = gc.getPlayer(CyGame().getActivePlayer())

        # Get the screen
        screen = self.getScreen()

        szName = ""
        iCost = 0

        if (self.m_iSelectedTech != -1):
            szName = gc.getTechInfo(self.m_iSelectedTech).getDescription()
            iCost = gc.getPlayer(CyGame().getActivePlayer()).getAdvancedStartTechCost(self.m_iSelectedTech, True)

        if iCost > 0:
            szText = u"<font=4>" + localText.getText("TXT_KEY_WB_AS_SELECTED_TECH_COST", (iCost, pPlayer.getAdvancedStartPoints())) + u"</font>"
            screen.setLabel( "ASPointsLabel", "Background", szText, CvUtil.FONT_LEFT_JUSTIFY, self.X_ADVANCED_START_TEXT, self.Y_ADD_TECH_BUTTON + 3, 0, FontTypes.TITLE_FONT, WidgetTypes.WIDGET_GENERAL, -1, -1 )
        else:
            screen.hide("ASPointsLabel")

        szText = u"<font=4>"
        szText += localText.getText("TXT_KEY_WB_AS_SELECTED_TECH", (szName,))
        szText += u"</font>"
        screen.setLabel( "SelectedTechLabel", "Background", szText, CvUtil.FONT_LEFT_JUSTIFY, self.X_ADVANCED_START_TEXT + 250, self.Y_ADD_TECH_BUTTON + 3, 0, FontTypes.TITLE_FONT, WidgetTypes.WIDGET_GENERAL, -1, -1 )

        # Want to add
        if (pPlayer.getAdvancedStartTechCost(self.m_iSelectedTech, True) != -1):
            screen.show("AddTechButton")
        else:
            screen.hide("AddTechButton")

    def onClose(self):
        pPlayer = gc.getPlayer(self.iCivSelected)
        if (pPlayer.getAdvancedStartPoints() >= 0):
            CyInterface().setDirty(InterfaceDirtyBits.Advanced_Start_DIRTY_BIT, True)
        return 0

class TechChooserMaps:

    TechChooserInputMap = {
        'TechRecord'            : CvTechChooser().TechRecord,
        'TechID'                : CvTechChooser().ParentClick,
        'TechPane'                : CvTechChooser().ParentClick,
        'TechButtonID'            : CvTechChooser().ParentClick,
        'TechButtonBorder'        : CvTechChooser().ParentClick,
        'Unit'                    : CvTechChooser().ParentClick,
        'Building'                : CvTechChooser().ParentClick,
        'Obsolete'                : CvTechChooser().ParentClick,
        'ObsoleteX'                : CvTechChooser().ParentClick,
        'Move'                    : CvTechChooser().ParentClick,
        'FreeUnit'                : CvTechChooser().ParentClick,
        'FeatureProduction'            : CvTechChooser().ParentClick,
        'Worker'                : CvTechChooser().ParentClick,
        'TradeRoutes'            : CvTechChooser().ParentClick,
        'HealthRate'            : CvTechChooser().ParentClick,
        'HappinessRate'            : CvTechChooser().ParentClick,
        'FreeTech'                : CvTechChooser().ParentClick,
        'LOS'                    : CvTechChooser().ParentClick,
        'MapCenter'                : CvTechChooser().ParentClick,
        'MapReveal'                : CvTechChooser().ParentClick,
        'MapTrade'                : CvTechChooser().ParentClick,
        'TechTrade'                : CvTechChooser().ParentClick,
        'OpenBorders'        : CvTechChooser().ParentClick,
        'BuildBridge'            : CvTechChooser().ParentClick,
        'Irrigation'            : CvTechChooser().ParentClick,
        'Improvement'            : CvTechChooser().ParentClick,
        'DomainExtraMoves'            : CvTechChooser().ParentClick,
        'AdjustButton'            : CvTechChooser().ParentClick,
        'TerrainTradeButton'    : CvTechChooser().ParentClick,
        'SpecialBuildingButton'    : CvTechChooser().ParentClick,
        'YieldChangeButton'        : CvTechChooser().ParentClick,
        'BonusRevealButton'        : CvTechChooser().ParentClick,
        'CivicRevealButton'        : CvTechChooser().ParentClick,
        'ProjectInfoButton'        : CvTechChooser().ParentClick,
        'ProcessInfoButton'        : CvTechChooser().ParentClick,
        'FoundReligionButton'    : CvTechChooser().ParentClick,
        'CivDropDown'            : CvTechChooser().CivDropDown,
        }

Hi Zeta,

In my modding of ROM AND2 I would like to do exactly the same thing what you've mentioned in this post. I have done the TechIcon size, TechName position and TechPanel button positions so far.

Have you found the way of widening TechPanels in this mode? I would like to do roughly 1.5x wide on each (same size on all).
By the way, I would increase the text font size as well a bit.
Can you (or anyone) help me?
 
Hi all, can somebody tell me what this python error log means..? I

Traceback (most recent call last):
File "CvScreensInterface", line 442, in pediaMain
File "SevoPediaMain", line 263, in pediaJump
File "SevoPediaMain", line 322, in showContents
File "SevoPediaMain", line 552, in placeNationalWonders
File "SevoPediaMain", line 834, in placeItems
RuntimeError: unidentifiable C++ exception
ERR: Python function pediaMain failed, module CvScreensInterface
 
Last edited:
Hi Zeta,

In my modding of ROM AND2 I would like to do exactly the same thing what you've mentioned in this post. I have done the TechIcon size, TechName position and TechPanel button positions so far.

Have you found the way of widening TechPanels in this mode? I would like to do roughly 1.5x wide on each (same size on all).
By the way, I would increase the text font size as well a bit.
Can you (or anyone) help me?
Actually I have totally forgot about it. :lol:
I tried it this morning but with only partial success (increased the tech icon size but it covers tech name and unblockable content).
Can you share your file, your changes?
 
Hi all, can somebody tell me what this python error log means..? I

Traceback (most recent call last):
File "CvScreensInterface", line 442, in pediaMain
File "SevoPediaMain", line 263, in pediaJump
File "SevoPediaMain", line 322, in showContents
File "SevoPediaMain", line 552, in placeNationalWonders
File "SevoPediaMain", line 834, in placeItems
RuntimeError: unidentifiable C++ exception
ERR: Python function pediaMain failed, module CvScreensInterface
I looked at my versions of SevoPedia but the line numbers don't line up. It usually means there is something wrong with what is being displayed. It is probably not a wrong sized icon or two items with the same name, as those cause other problems:lol:. I would need to see that python module (SevoPediaMain.py) to be able to help more.
 
I looked at my versions of SevoPedia but the line numbers don't line up. It usually means there is something wrong with what is being displayed. It is probably not a wrong sized icon or two items with the same name, as those cause other problems:lol:. I would need to see that python module (SevoPediaMain.py) to be able to help more.

Hi, heres main.py if you really have time to check:) this error cause pedia not working (building and techs) and trying to use it will crash game.. also if try to star game it will open without UI.
 

Attachments

Hi Zeta,

There is a good news, I finished completely my TechTree (see uploaded CvTechChooser.py file and some pics). :)

I used Note++.

1. TechName
Line 417: (szTechID, szTechRecord, szTechString, CvUtil.FONT_LEFT_JUSTIFY, iX + 6 + X_INCREMENT*2, iY + 6, -0.1, FontTypes.SMALL_FONT, WidgetTypes.WIDGET_TECH_TREE, i, -1)
Line 1146: (szTechID, sPanel, szTechString, CvUtil.FONT_LEFT_JUSTIFY, iX + 6 + X_INCREMENT*2, iY + 6, -0.1, FontTypes.SMALL_FONT, WidgetTypes.WIDGET_TECH_TREE, i, -1)

2. TechIcon size & TechName positioning
Line 422: (szTechButtonID, szTechRecord, gc.getTechInfo(i).getButton(), iX + 6, iY + 6, TEXTURE_SIZE*2, TEXTURE_SIZE*2, WidgetTypes.WIDGET_TECH_TREE, i, -1, False)
Line 1146: (szTechID, sPanel, szTechString, CvUtil.FONT_LEFT_JUSTIFY, iX + 6 + X_INCREMENT*2, iY + 6, -0.1, FontTypes.SMALL_FONT, WidgetTypes.WIDGET_TECH_TREE, i, -1)

3. TechPanel button positions
Line 425: (screen, i, X_START+ X_INCREMENT*2, iX, iY - 3, szTechRecord)

4. TechPanel lenghtening
Line 107, 256, 263, 267, 1079, 1084: BOX_INCREMENT_WIDTH = 30

5. I changed the colours of all era and the colour of selecting requested tech.
If you don't like my style, just ignore this part or you can adjust the numbers in RGB system:

Line 373: (szTechRecord, 255, 255, 0) - yellow for current research
Line 376: (szTechRecord, 255, 0, 0) - red for researching tech

Line 383: (szTechRecord, 96, 42, 30) - Ancient
Line 386: (szTechRecord, 50, 55, 2) - Classical
Line 389: (szTechRecord, 0, 96, 18) - Medieval
Line 392: (szTechRecord, 0, 74, 74) - Renaissance
Line 395: (szTechRecord, 0, 55, 85) - Industrial
Line 398: (szTechRecord, 0, 0, 122) - Modern
Line 401: (szTechRecord, 124, 0, 130) - Future

then the same in

Line 1152: (szTechRecord, 255, 255, 0) - yellow for current research
Line 1154: (szTechRecord, 255, 0, 0) - red for researching tech

Line 1160: (szTechRecord, 96, 42, 30) - Ancient
Line 1163: (szTechRecord, 50, 55, 2) - Classical
Line 1166: (szTechRecord, 0, 96, 18) - Medieval
Line 1169: (szTechRecord, 0, 74, 74) - Renaissance
Line 1172: (szTechRecord, 0, 55, 85) - Industrial
Line 98: (szTechRecord, 0, 0, 122) - Modern
Line 401: (szTechRecord, 124, 0, 130) - Future
 

Attachments

  • Current research & Researching.jpg
    Current research & Researching.jpg
    114.6 KB · Views: 74
  • ROM AND - TechTree 01b.jpg
    ROM AND - TechTree 01b.jpg
    102.6 KB · Views: 71
Hi,

I’m trying to cycle through the yields and get the yield value on some plots.
I’m currently trying,
Code:
for i in range(YieldTypes.NUM_YIELD_TYPES):
   plotYield = pPlot.getYield(i)

This is now giving me a, “ this constructor takes no arguments” error.
In CyPlot.h, the function is
int getYield(YieldTypes eIndex).

How do I get this to work?
 
Looks like getYield expects a YieldTypes enum type. So I think you could use something like
Code:
pPlot.getYield(YieldTypes(i))
(but I haven't tested that so I might be wrong.)
 
Is there an existing, XML-only way to make multiple buildings mutually exclusive? I am thinking about a bunch of early buildings that require a Palace and an give early specialist slots, but each civ should only be allowed to have one of them.

If not, what is the most elegant way to solve this? I am thinking of giving SpecialBuildings a "max player instances" attribute and make all those buildings instances of the same special building.
 
Hi, heres main.py if you really have time to check:) this error cause pedia not working (building and techs) and trying to use it will crash game.. also if try to star game it will open without UI.

Here's the line in question -

Code:
screen.setTableText(self.ITEM_LIST_ID, 0, i, u"<font=3>" + item[0] + u"</font>", info(item[1]).getButton(), widget, data1, data2, CvUtil.FONT_LEFT_JUSTIFY)

For reference, here's the same sort of line in the normal CvPediaMain.py:

Code:
screen.setTableText(tableName, iColumn, iRow, u"<font=3>" + item[0] + u"</font>", gc.getTechInfo(item[1]).getButton(), WidgetTypes.WIDGET_PEDIA_JUMP_TO_TECH, item[1], 1, CvUtil.FONT_LEFT_JUSTIFY)

I don't see anything obviously wrong, but the info(item[1]).getButton() seems fishy for some reason. Usually when I get a C++ exception it's because I am referring to something that I think exists, but doesn't actually; for example, using gc.getInfoTypeForString("TECH_RADAR") when I haven't actually added TECH_RADAR to the xml. In this case, I'm betting that whatever that "info(item[1])" is, it's been messed up somewhere so that it no longer refers to what it should be referring to.

It could be something else in that line doing the same thing...but nothing jumps out at me.
 
Where can I find and edit the text marked with yellow?
View attachment 564481

All of the text in the victory screen seems to be set up in roughly lines 500-600 of CvVictoryScreen.py. But if you want to just find the text and edit it directly, you can search around in your mod's XML/Text files for whichever one says "ascension" and change it there.

It's possible that whatever mod builds that part of the victory screen using the name of the building rather than any specific text - for example, "Build" followed by TXT_KEY_BUILDING_GATEOFASCENSION (or even pBuilding.getDescription()) in which case you'd have to edit the lines in CvVictoryScreen if you want to change it beyond that.

That's the place Platyping adds text for new victory mods.
 
Is there an existing, XML-only way to make multiple buildings mutually exclusive? I am thinking about a bunch of early buildings that require a Palace and an give early specialist slots, but each civ should only be allowed to have one of them.

If not, what is the most elegant way to solve this? I am thinking of giving SpecialBuildings a "max player instances" attribute and make all those buildings instances of the same special building.

First, I'm not sure, but buildings aren't able to require other buildings, are they? There are mods that do that but I'm pretty sure vanilla doesn't let you require buildings to build buildings. (Although you can get around it by having the building be required for a unit, which then builds its own building, like a military academy for great generals.)

Edit: I just found BuildingClassNeededs in the XML and it changed my life.

Second, I don't know about "elegant"...but I can think of some ways I'd tackle this:
  1. The max player instances for specialbuildings would work but requires SDK (though not that much SDK)
  2. Using purely XML, you could have an event with a trigger of iWeight = -1, whose only condition is building a certain building. Then use this building ("BUILDING_DUMMY" or something) to trigger a set of events where the player can choose between different buildings to build in the city. The event trigger can be set to trigger only once. Problem with this is that the AI might not know to build the dummy building unless you give it some benefit, and removing the dummy building would require python (but would be really easy). Or, you could just set the event to trigger when the first city is founded and shortcut all the dummy building stuff.
  3. Using python, you could mess around in canConstruct in CvGameUtils and whip out the mutual exclusion pretty easily. Probably not very elegant but very easy. (Although you would have to check to make sure the building isn't built in any of the player's cities, which could become a big loop - though I suppose you could just check whatever city the palace is in, because the buildings will require the palace)
  4. With SDK you could add a list tag to the BuildingInfos tile, like <CannotBuildBuildings>, that lists buildings that, if built in the city, will make this building unable to be built. But that seems like just a slightly more complicated way to do the SpecialBuilding thing you were saying.
  5. Or with XML you could just make the buildings National Wonders and limit each city to 1 national wonder. But that would also exclude other national wonders, and wouldn't keep the whole civ from building the other buildings, just that one city.
  6. Combining python with XML you could do some fancy tech trigger thing where once one of the buildings is built, something is triggered that removes the tech necessary to build all the other buildings. Might work a little better than the dummy building thing or the canConstruct but it's a little more complicated.
 
Last edited:
Is there an existing, XML-only way to make multiple buildings mutually exclusive? I am thinking about a bunch of early buildings that require a Palace and an give early specialist slots, but each civ should only be allowed to have one of them.

If not, what is the most elegant way to solve this? I am thinking of giving SpecialBuildings a "max player instances" attribute and make all those buildings instances of the same special building.
Afforess has added some code for AND that does just the thing you want:
Code:
            <PrereqNotBuildingClasses>
                <PrereqNotBuildingClass>
                    <BuildingClassMustNotHave>BUILDINGCLASS_NEWTONS_UNIVERSITY</BuildingClassMustNotHave>
                    <bPrereqNot>1</bPrereqNot>
                </PrereqNotBuildingClass>
                <PrereqNotBuildingClass>
                    <BuildingClassMustNotHave>BUILDINGCLASS_LEONARDO</BuildingClassMustNotHave>
                    <bPrereqNot>1</bPrereqNot>
                </PrereqNotBuildingClass>
            </PrereqNotBuildingClasses>
With the code above a city cannot build the Copernicus Observatory if it already has Newton's University or Leonardo's Workshop.
 
Great, thanks! I am not opposed to editing the DLL, I just want to do it the least invasive way. And make sure I am not missing an already existing way to do this.
 
Back
Top Bottom