Adding a new box to the civlopedia for civ powers

j_mie6

Deity
Joined
Dec 20, 2009
Messages
2,963
Location
Bristol (uni)/Swindon (home)
Hello,

I was wondering if there is anyway of displaying a new little box in the Pedia which gives information about a civ's unique power...

Does anybody know how to create a box in a civ's pedia entry where the power info could be stored?

I am guessing the CvPediaCivilization.py file would be used
Spoiler :

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

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

class CvPediaCivilization:
	"Civilopedia Screen for Civilizations"

	def __init__(self, main):
		self.iCivilization = -1
		self.top = main
		
		self.X_MAIN_PANE = 50
		self.Y_MAIN_PANE = 90
		self.W_MAIN_PANE = 250
		self.H_MAIN_PANE = 210

		self.X_ICON = 98
		self.Y_ICON = 125
		self.W_ICON = 150
		self.H_ICON = 150
		self.ICON_SIZE = 64

		self.X_TECH = 330
		self.Y_TECH = 70
		self.W_TECH = 200
		self.H_TECH = 110

		self.X_BUILDING = 555
		self.Y_BUILDING = 190
		self.W_BUILDING = 200
		self.H_BUILDING = 110

		self.X_UNIT = 330
		self.Y_UNIT = 190
		self.W_UNIT = 200
		self.H_UNIT = 110

		self.X_LEADER = 555
		self.Y_LEADER = 70
		self.W_LEADER = 200
		self.H_LEADER = 110

		self.X_TEXT = self.X_MAIN_PANE
		self.Y_TEXT = self.Y_MAIN_PANE + self.H_MAIN_PANE + 20
		self.W_TEXT = 705
		self.H_TEXT = 350
		
	# Screen construction function
	def interfaceScreen(self, iCivilization):	
			
		self.iCivilization = iCivilization
	
		self.top.deleteAllWidgets()						
							
		screen = self.top.getScreen()
		
		bNotActive = (not screen.isActive())
		if bNotActive:
			self.top.setPediaCommonWidgets()

		# Header...
		szHeader = u"<font=4b>" + gc.getCivilizationInfo(self.iCivilization).getDescription().upper() + u"</font>"
		szHeaderId = self.top.getNextWidgetName()
		screen.setLabel(szHeaderId, "Background", szHeader, CvUtil.FONT_CENTER_JUSTIFY, self.top.X_SCREEN, self.top.Y_TITLE, 0, FontTypes.TITLE_FONT, WidgetTypes.WIDGET_GENERAL, -1, -1)
		
		# Top
		screen.setText(self.top.getNextWidgetName(), "Background", self.top.MENU_TEXT, CvUtil.FONT_LEFT_JUSTIFY, self.top.X_MENU, self.top.Y_MENU, 0, FontTypes.TITLE_FONT, WidgetTypes.WIDGET_PEDIA_MAIN, CivilopediaPageTypes.CIVILOPEDIA_PAGE_CIV, -1)

		if self.top.iLastScreen	!= CvScreenEnums.PEDIA_CIVILIZATION or bNotActive:		
			self.placeLinks(true)
			self.top.iLastScreen = CvScreenEnums.PEDIA_CIVILIZATION
		else:
			self.placeLinks(false)
			
		# Icon
		screen.addPanel( self.top.getNextWidgetName(), "", "", False, False,
		    self.X_MAIN_PANE, self.Y_MAIN_PANE, self.W_MAIN_PANE, self.H_MAIN_PANE, PanelStyles.PANEL_STYLE_BLUE50)
		screen.addPanel(self.top.getNextWidgetName(), "", "", false, false,
		    self.X_ICON, self.Y_ICON, self.W_ICON, self.H_ICON, PanelStyles.PANEL_STYLE_MAIN)
		screen.addDDSGFC(self.top.getNextWidgetName(), ArtFileMgr.getCivilizationArtInfo(gc.getCivilizationInfo(self.iCivilization).getArtDefineTag()).getButton(),
		    self.X_ICON + self.W_ICON/2 - self.ICON_SIZE/2, self.Y_ICON + self.H_ICON/2 - self.ICON_SIZE/2, self.ICON_SIZE, self.ICON_SIZE, WidgetTypes.WIDGET_GENERAL, -1, -1 )

		self.placeTech()
		self.placeBuilding()
		self.placeUnit()
		self.placeLeader()
		self.placeText()

		return

	def placeTech(self):
		
		screen = self.top.getScreen()
		
		panelName = self.top.getNextWidgetName()
		screen.addPanel( panelName, localText.getText("TXT_KEY_FREE_TECHS", ()), "", false, true,
				 self.X_TECH, self.Y_TECH, self.W_TECH, self.H_TECH, PanelStyles.PANEL_STYLE_BLUE50 )
		screen.attachLabel(panelName, "", "  ")
		
		for iTech in range(gc.getNumTechInfos()):
			if (gc.getCivilizationInfo(self.iCivilization).isCivilizationFreeTechs(iTech)):
				screen.attachImageButton( panelName, "", gc.getTechInfo(iTech).getButton(), GenericButtonSizes.BUTTON_SIZE_CUSTOM, WidgetTypes.WIDGET_PEDIA_JUMP_TO_TECH, iTech, 1, False )
	
	def placeBuilding(self):
		
		screen = self.top.getScreen()
		
		panelName = self.top.getNextWidgetName()
		screen.addPanel( panelName, localText.getText("TXT_KEY_UNIQUE_BUILDINGS", ()), "", false, true,
				self.X_BUILDING, self.Y_BUILDING, self.W_BUILDING, self.H_BUILDING, PanelStyles.PANEL_STYLE_BLUE50 )
		screen.attachLabel(panelName, "", "  ")
		
		for iBuilding in range(gc.getNumBuildingClassInfos()):
			iUniqueBuilding = gc.getCivilizationInfo(self.iCivilization).getCivilizationBuildings(iBuilding);
			iDefaultBuilding = gc.getBuildingClassInfo(iBuilding).getDefaultBuildingIndex();
			if (iDefaultBuilding > -1 and iUniqueBuilding > -1 and iDefaultBuilding != iUniqueBuilding):
				screen.attachImageButton( panelName, "", gc.getBuildingInfo(iUniqueBuilding).getButton(), GenericButtonSizes.BUTTON_SIZE_CUSTOM, WidgetTypes.WIDGET_PEDIA_JUMP_TO_BUILDING, iUniqueBuilding, 1, False )
				
	def placeUnit(self):
		
		screen = self.top.getScreen()
		
		panelName = self.top.getNextWidgetName()
		screen.addPanel( panelName, localText.getText("TXT_KEY_FREE_UNITS", ()), "", false, true,
				 self.X_UNIT, self.Y_UNIT, self.W_UNIT, self.H_UNIT, PanelStyles.PANEL_STYLE_BLUE50 )
		screen.attachLabel(panelName, "", "  ")
					
		for iUnit in range(gc.getNumUnitClassInfos()):
			iUniqueUnit = gc.getCivilizationInfo(self.iCivilization).getCivilizationUnits(iUnit);
			iDefaultUnit = gc.getUnitClassInfo(iUnit).getDefaultUnitIndex();
			if (iDefaultUnit > -1 and iUniqueUnit > -1 and iDefaultUnit != iUniqueUnit):
				szButton = gc.getUnitInfo(iUniqueUnit).getButton()
				if self.top.iActivePlayer != -1:
					szButton = gc.getPlayer(self.top.iActivePlayer).getUnitButton(iUniqueUnit)
				screen.attachImageButton( panelName, "", szButton, GenericButtonSizes.BUTTON_SIZE_CUSTOM, WidgetTypes.WIDGET_PEDIA_JUMP_TO_UNIT, iUniqueUnit, 1, False )
		
	def placeLeader(self):
		
		screen = self.top.getScreen()
		
		panelName = self.top.getNextWidgetName()
		screen.addPanel( panelName, localText.getText("TXT_KEY_CONCEPT_LEADERS", ()), "", false, true,
				 self.X_LEADER, self.Y_LEADER, self.W_LEADER, self.H_LEADER, PanelStyles.PANEL_STYLE_BLUE50 )
		screen.attachLabel(panelName, "", "  ")

		for iLeader in range(gc.getNumLeaderHeadInfos()):
			civ = gc.getCivilizationInfo(self.iCivilization)
			if civ.isLeaders(iLeader):
				screen.attachImageButton( panelName, "", gc.getLeaderHeadInfo(iLeader).getButton(), GenericButtonSizes.BUTTON_SIZE_CUSTOM, WidgetTypes.WIDGET_PEDIA_JUMP_TO_LEADER, iLeader, self.iCivilization, False )
		
	def placeText(self):
		
		screen = self.top.getScreen()
		
		panelName = self.top.getNextWidgetName()
		screen.addPanel( panelName, "", "", true, true,
				 self.X_TEXT, self.Y_TEXT, self.W_TEXT, self.H_TEXT, PanelStyles.PANEL_STYLE_BLUE50 )
 
		szText = gc.getCivilizationInfo(self.iCivilization).getCivilopedia()
		screen.attachMultilineText( panelName, "Text", szText, WidgetTypes.WIDGET_GENERAL, -1, -1, CvUtil.FONT_LEFT_JUSTIFY)
													
	def placeLinks(self, bRedraw):

		screen = self.top.getScreen()

		if bRedraw:	
			screen.clearListBoxGFC(self.top.LIST_ID)
		
		# sort Improvements alphabetically
		listSorted=[(0,0)]*gc.getNumCivilizationInfos()
		for j in range(gc.getNumCivilizationInfos()):
			listSorted[j] = (gc.getCivilizationInfo(j).getDescription(), j)
		listSorted.sort()	
			
		iSelected = 0
		i = 0
		for iI in range(gc.getNumCivilizationInfos()):
			if (gc.getCivilizationInfo(listSorted[iI][1]).isPlayable() and not gc.getCivilizationInfo(listSorted[iI][1]).isGraphicalOnly()):
				if (not gc.getDefineINT("CIVILOPEDIA_SHOW_ACTIVE_CIVS_ONLY") or not gc.getGame().isFinalInitialized() or gc.getGame().isCivEverActive(listSorted[iI][1])):
					if bRedraw:
						screen.appendListBoxStringNoUpdate(self.top.LIST_ID, listSorted[iI][0], WidgetTypes.WIDGET_PEDIA_JUMP_TO_CIV, listSorted[iI][1], 0, CvUtil.FONT_LEFT_JUSTIFY )
					if listSorted[iI][1] == self.iCivilization:
						iSelected = i
					i += 1
					
		if bRedraw:
			screen.updateListBox(self.top.LIST_ID)
					
		screen.setSelectedListBoxStringGFC(self.top.LIST_ID, iSelected)
			

	# Will handle the input for this screen...
	def handleInput (self, inputClass):
		return 0


Thanks in advance,
Jamie
 
You pretty much do waht it does for the other things, like tech or building. You need to rearrange the layout by adjusting the numbers for the other things to make room for it. You can often reduce the spacing between the various panels things are shown in/on as well as to make them a little smaller if all you need is a couple of lines.

For an alternative, and easier to implement, solution you could put it at the beginning of the civilization's text by, in placeText, setting szText to be the text for the power and then appending the existing civilopedia text to it (probably with a line break and blank line added between them, maybe a header line that says something like "Civilization Power", and things like that).
 
I kinda guessed about the rearranging but I'm not sure how to do it... like how to move the boxes and create the new one...
 
My suggestion for altering the layout:

Diagrams are your friend in situations like this.

Take a screen shot showing the screen you wnat to change. Open it in some graphics program. Then refer to the Python to get the positions of everything and mark up the screen shot with the values.
Code:
		self.X_TECH = 330
		self.Y_TECH = 70
		self.W_TECH = 200
		self.H_TECH = 110
These are the X,Y position of one of the corners of the panel that shows the techs and tis width and height. By looking at the Y values you can determine if it counts up from the bottom or down from the top (I can never remember). The X values are distance in from the left. So the tech panel starts 330 units (it may be 1 unit = 1 pixel) in from the left and is 200 units wide, giving it an X range of 330 to 530.

Once everything is marked you can figure out how much space is between the elements to see how much room you can squeeze out of that. Figure out what to change them to and what the new panel's coordinates should be. And so on.

You might be able to make the main screen bigger (making the whole panel bigger on your screen).

There may be some (relatively) empty space that you can use. I mostly use mods that use the Sevopedia these days, and don't really remember what the original one looks like...
 
I did it! the Y counts from the top btw

Code:
        def placePower(self):

                screen = self.top.getScreen()

                panelName = self.top.getNextWidgetName()
                screen.addPanel( panelName, localText.getText("TXT_KEY_PEDIA_TITLE_POWERS", ()), "", false, false,
                                 self.X_POWER, self.Y_POWER, self.W_POWER, self.H_POWER, PanelStyles.PANEL_STYLE_BLUE50 )

                #Power dict takes form out of the order in CivilizationInfos.xml
                dPowerDict = {6 : "TXT_KEY_PEDIA_ROME_POWER",
                              5 : "TXT_KEY_PEDIA_GREECE_POWER",
                              3 : "TXT_KEY_PEDIA_BRITTANIA_POWER",
                              2 : "TXT_KEY_PEDIA_GAUL_POWER",
                              1 : "TXT_KEY_PEDIA_CARTHAGE_POWER",
                              4 : "TXT_KEY_PEDIA_EGYPT_POWER",
                              7 : "TXT_KEY_PEDIA_GERMANIA_POWER",
                              8 : "TXT_KEY_PEDIA_PICTIA_POWER"}

                sText = localText.getText(dPowerDict.get(self.iCivilization, "TXT_KEY_PEDIA_NONE_POWER"), ())
                screen.attachMultilineText( panelName, "Power", sText, WidgetTypes.WIDGET_GENERAL, -1, -1, CvUtil.FONT_LEFT_JUSTIFY)

looks good!
 
Before I could do the screenshot I wanted to turn that python dict code into C++ code so that whole block became:

Code:
sText = localText.getText(str(gc.getCivilizationInfo(self.iCivilization).getPowerDescription()), ())

getPowerDescription() is the first C++ function I have ever made and it collects the data from an optional xml tag of <Power>TXT_KEY_</Power> in CivilizationInfos.xml which stores that dict instead! First time I have ever used the DLL, took ages :rolleyes:
 
Back
Top Bottom