There has been alot of discussion on this topic since Civ4 came out and several ways to make it work have been discovered, but I think I have figured out a pretty clean way to do it with python.
First step would be to set up the TechInfo.xml with the multiple tech trees.
TechA1 -> TechA2 -> TechA3
TechB1 -> TechB2 -> TechB3
The next step is to make the different trees unresearchable by specific players. This can be pretty easyly accomplished with the cannotResearch method in the CvGameUtils.py file. The real code would be in a function that checks if a given Player has access to a given Tech, say isTechValid(iPlayer, iTech), that returns True or False.
The last step, and the one that I don't think anyone has come up with a good fix for, is displaying a correct looking tech tree on the Tech Advisor screen. However, I think the answer just hit me and after looking at the Tech Advisor screen code I'm pretty sure it will work.
In the CvTechChosser.py file, in the placeTechs() method.
Code:
def placeTechs (self):
iMaxX = 0
iMaxY = 0
# If we are the Pitboss, we don't want to put up an interface at all
if ( CyGame().isPitbossHost() ):
return
# Get the screen
screen = CyGInterfaceScreen( "TechChooser", CvScreenEnums.TECH_CHOOSER )
# Go through all the techs
for i in range(gc.getNumTechInfos()):
# Create and place a tech in its proper location
iX = 30 + ( (gc.getTechInfo(i).getGridX() - 1) * ( ( BOX_INCREMENT_X_SPACING + BOX_INCREMENT_WIDTH ) * PIXEL_INCREMENT ) )
iY = ( gc.getTechInfo(i).getGridY() - 1 ) * ( BOX_INCREMENT_Y_SPACING * PIXEL_INCREMENT ) + 5
szTechRecord = "TechRecord" + str(i)
if ( iMaxX < iX + self.getXStart() ):
iMaxX = iX + self.getXStart()
if ( iMaxY < iY + ( BOX_INCREMENT_HEIGHT * PIXEL_INCREMENT ) ):
iMaxY = iY + ( BOX_INCREMENT_HEIGHT * PIXEL_INCREMENT )
screen.attachPanelAt( "TechList", szTechRecord, u"", u"", True, False, PanelStyles.PANEL_STYLE_TECH, iX - 6, iY - 6, self.getXStart() + 6, 12 + ( BOX_INCREMENT_HEIGHT * PIXEL_INCREMENT ), WidgetTypes.WIDGET_TECH_TREE, i, -1 )
screen.setActivation( szTechRecord, ActivationTypes.ACTIVATE_MIMICPARENTFOCUS)
screen.hide( szTechRecord )
This just goes through all the techs in the xml file and places them at the proper x, y coords on the Tech Advisor screen.
If you change it to something like this
Code:
def placeTechs (self):
iMaxX = 0
iMaxY = 0
# If we are the Pitboss, we don't want to put up an interface at all
if ( CyGame().isPitbossHost() ):
return
# Get the screen
screen = CyGInterfaceScreen( "TechChooser", CvScreenEnums.TECH_CHOOSER )
# Go through all the techs
for i in range(gc.getNumTechInfos()):
if(not isTechValid(gc.getGame().getActivePlayer(), i)):
continue
# Create and place a tech in its proper location
iX = 30 + ( (gc.getTechInfo(i).getGridX() - 1) * ( ( BOX_INCREMENT_X_SPACING + BOX_INCREMENT_WIDTH ) * PIXEL_INCREMENT ) )
iY = ( gc.getTechInfo(i).getGridY() - 1 ) * ( BOX_INCREMENT_Y_SPACING * PIXEL_INCREMENT ) + 5
szTechRecord = "TechRecord" + str(i)
then only techs in the proper tech tree will be displayed. You will then be able to set each tech tree up as if the others don't exist.
I have a few free hours, I'm going to look into making an example mod of this, should be able to get it done tonight.