only display highest level promo?

davidlallen

Deity
Joined
Apr 28, 2008
Messages
4,743
Location
California
I know some other mods have done this, but I can't find a place to get started. To reduce the number of promotions shown for high level units, I'd like to suppress drawing of Combat 1 for a unit which also has Combat II, and so on. The screenie shows a warrior with Combat IV. I'd like to only draw one icon, the Combat IV one.



I can see how to put a data member into the CvPromotions object, "CoveredBy", so Combat I says "covered by Combat II". But, I can't see where to go in the graphics routines to skip drawing the covered icons.

Can anybody point me?
 

Attachments

  • unstacked.gif
    unstacked.gif
    9.8 KB · Views: 195
If you want to hide the low level promotions like in FFHII, you need to modify the CvMainInterface.
It should be under def updateInfoPaneStrings( self ):, scroll to the end of the function and you should see this:
Spoiler :
Code:
					if ((pHeadSelectedUnit.getExperience() > 0) and not pHeadSelectedUnit.isFighting()):
						szLeftBuffer = localText.getText("INTERFACE_PANE_EXPERIENCE", ())
						szRightBuffer = u"(%d/%d)" %(pHeadSelectedUnit.getExperience(), pHeadSelectedUnit.experienceNeeded())
						szBuffer = szLeftBuffer + "  " + szRightBuffer
						screen.appendTableRow( "SelectedUnitText" )
						screen.setTableText( "SelectedUnitText", 0, iRow, szLeftBuffer, "", WidgetTypes.WIDGET_HELP_SELECTED, -1, -1, CvUtil.FONT_LEFT_JUSTIFY )
						screen.setTableText( "SelectedUnitText", 1, iRow, szRightBuffer, "", WidgetTypes.WIDGET_HELP_SELECTED, -1, -1, CvUtil.FONT_RIGHT_JUSTIFY )
						screen.show( "SelectedUnitText" )
						screen.show( "SelectedUnitPanel" )
						iRow += 1

					[COLOR="Red"]iPromotionCount = 0
					i = 0
					for i in range(gc.getNumPromotionInfos()):
						if (pHeadSelectedUnit.isHasPromotion(i)):
							szName = "PromotionButton" + str(i)
							self.setPromotionButtonPosition( szName, iPromotionCount )
							screen.moveToFront( szName )
							screen.show( szName )

							iPromotionCount = iPromotionCount + 1[/COLOR]

			if (pSelectedGroup):
			
				iNodeCount = pSelectedGroup.getLengthMissionQueue()

				if (iNodeCount > 1):
					for i in range( iNodeCount ):
						szLeftBuffer = u""
						szRightBuffer = u""
					
						if (gc.getMissionInfo(pSelectedGroup.getMissionType(i)).isBuild()):
							if (i == 0):
								szLeftBuffer = gc.getBuildInfo(pSelectedGroup.getMissionData1(i)).getDescription()
								szRightBuffer = localText.getText("INTERFACE_CITY_TURNS", (pSelectedGroup.plot().getBuildTurnsLeft(pSelectedGroup.getMissionData1(i), 0, 0), ))								
							else:
								szLeftBuffer = u"%s..." %(gc.getBuildInfo(pSelectedGroup.getMissionData1(i)).getDescription())
						else:
							szLeftBuffer = u"%s..." %(gc.getMissionInfo(pSelectedGroup.getMissionType(i)).getDescription())

						szBuffer = szLeftBuffer + "  " + szRightBuffer
						screen.appendTableRow( "SelectedUnitText" )
						screen.setTableText( "SelectedUnitText", 0, iRow, szLeftBuffer, "", WidgetTypes.WIDGET_HELP_SELECTED, i, -1, CvUtil.FONT_LEFT_JUSTIFY )
						screen.setTableText( "SelectedUnitText", 1, iRow, szRightBuffer, "", WidgetTypes.WIDGET_HELP_SELECTED, i, -1, CvUtil.FONT_RIGHT_JUSTIFY )
						screen.show( "SelectedUnitText" )
						screen.show( "SelectedUnitPanel" )
						iRow += 1

		return 0
The red part shows the promotions. You just need to add a check if the promotion has a "CoveredBy" -promotion defined and if the unit has it. Something like this:
Spoiler :
Code:
					iPromotionCount = 0
					i = 0
					for i in range(gc.getNumPromotionInfos())
						[COLOR="Red"]iCoveredByProm = gc.getPromotionInfo(i).getPromotionCoveredBy()
						if (pHeadSelectedUnit.isHasPromotion(i) and (iCoveredByProm == -1 or pHeadSelectedUnit.isHasPromotion(iCoveredByProm) == False)):[/COLOR]
							szName = "PromotionButton" + str(i)
							self.setPromotionButtonPosition( szName, iPromotionCount )
							screen.moveToFront( szName )
							screen.show( szName )

							iPromotionCount = iPromotionCount + 1
Ofcourse you need to add the covered by tag to promotion infos. I haven't tested this but I'm quite sure it works.
 
Excellent, thanks for the quick reply. But, I forgot that these promotions appear in the unit hover help also, as shown at the top of this screenie:



Do you also know where those are drawn?
 

Attachments

  • stack-hover.gif
    stack-hover.gif
    23.3 KB · Views: 169
Excellent, thanks for the quick reply. But, I forgot that these promotions appear in the unit hover help also, as shown at the top of this screenie:

Do you also know where those are drawn?

I'm fairly sure it's drawn in DLL. setUnitHelp() in CvGameTextMgr.cpp might be the place.

EDIT: Oh, there seems to be two setUnitHelp functions. I think the void CvGameTextMgr::setUnitHelp(CvWStringBuffer &szString, const CvUnit* pUnit, bool bOneLine, bool bShort) is the one.
I'll test it...

EDIT2: Yes, that's the right one.
 
This is something I'd like to put into BUG and BULL. Could you please post your code?

Did you have to add the covered by field to the info object, or did you just hide those promos which are the single prereq of other promos? IOW, if Combat I is the only prereq of Combat II, hide it when the unit has C2.

Another thing I'd really like to add is to show the collective promotions of stacks of units in the info pane. So if you have two units selected, one with C1 Shock and the other with C1 CR1, it would show C1 CR1 Shock. Even better if it put little numbers over the icons (might be tough to read that though) so C1 would have a 2 in the corner.

Man, if I could just get myself a couple Python/C++ interns for the summer, BUG would have a lot of new features. So many ideas, so little time. :cry:
 
This is something I'd like to put into BUG and BULL. Could you please post your code?

Seconded.

Man, if I could just get myself a couple Python/C++ interns for the summer, BUG would have a lot of new features. So many ideas, so little time. :cry:

Why don't you create a thread, or search people out? ;)
 
The code is trivial but distributed. There are four steps.

1. Add a "CoveredBy" field to CvPromotions. This is done by following the steps of xienwolf's idiot guide, and it involves about 10 changes to cvinfos.h, cvinfos.cpp, and civ4unitschema.xml.

2. Add the "CoveredBy" data into civ4promotioninfos.xml. I thought about having code which tests the string of the names and if it finds a pattern like "xxxN", some text ending in an integer, then automatically make it covered by "xxx(N+1)". But it was easier to edit the file and add about 20 CoveredBy lines.

3. As pointed by NSG, prevent the icons from being drawn in cvmaininterface.py.

4. As later pointed by NSG, prevent the icons from being drawn in CvGameTextMgr::setUnitHelp.

I have attached these isolated files. But, these are based on vanilla (not BUG) and contain a number of my own unrelated changes. If you search "davidlallen stacked promotions" in the sdk and python files, you will see all my changes. I am always nervous about putting comments into the xml because of the weird xml parser, but if you search for "CoveredBy" in the schema and promotion file, you will see all my changes.
 

Attachments

  • stacked-promo.zip
    209.9 KB · Views: 51
Hmm, the promotions prereqs are very odd. There are three fields: prereq, or1, and or2. IIRC they are implemented like this:

prereq AND ( or1 OR or2 )​

All of the promotions* with a single prereq put it in the or1 field instead of the more obvious prereq field. For example, C2 requires <empty> and (C1 or <empty>), where <empty> is ignored of course. Perhaps it was done that way because Firaxis figured if you were going to add a prereq to an existing promotion you'd want it to be OR'd with the current prereq--not that it would be hard to move it. The only vanilla Civ4 exception is Navigation 2 which requires Flanking 1 (prereq) and Navigation 1 (or1).

* All of the promotions that require the Leader promotion given by a GG such as Leadership, Tactics, Combat6, etc. place it in the prereq field.​

In any case, what I noticed by looking at the file is that you can't just do what I had hoped and inspect the prereqs. Too many would cause confusion by hiding Combat line promotions in some cases. For example, a C1 C2 Amphibious unit would show only Amphibious since C2 is its only prereq. Unless you memorized the tree you wouldn't know which Combat promotions the unit had.

For BUG and BULL since I don't have the luxury of modifying CvPromotionInfos.xml, I'll fall back on what davidlallen was going to do originally: use the numbers at the end of the promotion keys. If two promotion keys differ only by their number, hide the one with the lower number.

Thanks for the code. :) At least I won't have to noodle much on the interface.
 
k
In any case, what I noticed by looking at the file is that you can't just do what I had hoped and inspect the prereqs. Too many would cause confusion by hiding Combat line promotions in some cases. For example, a C1 C2 Amphibious unit would show only Amphibious since C2 is its only prereq. Unless you memorized the tree you wouldn't know which Combat promotions the unit had.

Add an additional check that see's if the modifier(s) used are the same in the next promotion could solve this. So if a unit has Combat I and Combat II, it checks the prereqs, and that Combat II modifies the percent strength ( > 0).
 
First, that would require adding specific code to handle all of the different modifier types. Second, some promotions have multiple modifiers which would make it trickier. Or I could just compare two strings. Yeah, I'll with the latter. ;)
 
Top Bottom