.

Lord Olleus said:
Is there a way of changing what the on the screen text says depending on what is happening in the game. For example would it be possible to change TXT_KEY_MISSION_PILLAGE_HELP so that it tells you the name of the improvement that you are going to pillage?

There would be two things to change. The first is the entry in the text files themselves. You can take a look at a key that does this for you for an example.

Code:
<Tag>INTERFACE_PANE_UNIT_NAME</Tag> 
  <English>[COLOR_UNIT_TEXT]%s1[COLOR_REVERT]</English> 
  <French>[COLOR_UNIT_TEXT]%s1[COLOR_REVERT]</French> 
  <German>[COLOR_UNIT_TEXT]%s1[COLOR_REVERT]</German> 
  <Italian>[COLOR_UNIT_TEXT]%s1[COLOR_REVERT]</Italian> 
  <Spanish>[COLOR_UNIT_TEXT]%s1[COLOR_REVERT]</Spanish> 

</Tag>

This takes the first argument that will be passed into it, and places it in the text entry. What's also interesting to note is that it doesn't care what the language is. For this all to work though, you need to make sure all the calls to use that text key don't have an empty tuple in the second argument, but instead the name of the item.

Code:
szBuffer = localText.getText("INTERFACE_PANE_UNIT_NAME", ([b]pHeadSelectedUnit.getName(), [/b]))


This tuple only has one element, if it had two, you could use %s1 and %s2 in the txt_key entry for the first and second items in the tuple. I believe you can also use %f and %d for floats and integers.
 
Lord Olleus said:
great minds think alike. You wouldn't be interested in joining the Warhammer Mod by any chance? </ShamelessSelfAdvertising>


haha.. one's enough for me, thanks! I'm already coding Civcraft: SC, an ambitious mod combining the... ::gets yanked out by oversized cane::
 
Lord Olleus said:
Just one more question

Do you know which python file controlls the bottom central panel when units are selected? Thats the one where all the different icons for all the missions are displayed. I've looked at the code for hours but can't find it.

I believe it's stuck in the monstrosity of the main interface screen under the function updateSelectionButtons(), which is in itself a function over 300 lines long.

Edit: Too slow :P
 
Lord Olleus said:
Thanks. Unfortunately it doesn't do what I hoped it would. Do you know which file controlls the text that appears when you mouse over the selection buttons?

Ah. That's gonna' be in the SDK. CvDLLWidgetData.cpp has the function:

void CvDLLWidgetData:: parseTrainHelp that sets what that pop-up says, but just know this: most of what that function does is actually set using the setUnitInfo function, which is called at the end...

Code:
void CvDLLWidgetData::parseTrainHelp(CvWidgetDataStruct &widgetDataStruct, CvWString &szBuffer)
{
	CvCity* pHeadSelectedCity;
	UnitTypes eUnit;

	if (widgetDataStruct.m_iData2 != FFreeList::INVALID_INDEX)
	{
		pHeadSelectedCity = GET_PLAYER(GC.getGameINLINE().getActivePlayer()).getCity(widgetDataStruct.m_iData2);
	}
	else
	{
		pHeadSelectedCity = gDLL->getInterfaceIFace()->getHeadSelectedCity();
	}

	if (pHeadSelectedCity != NULL)
	{
		eUnit = (UnitTypes)GC.getCivilizationInfo(pHeadSelectedCity->getCivilizationType()).getCivilizationUnits(widgetDataStruct.m_iData1);

[b]		GAMETEXT.setUnitHelp(szBuffer, eUnit, false, widgetDataStruct.m_bOption, false, pHeadSelectedCity);[/b]
	}
}

So, that GAMETEXT.setUnitHelp will probably be what you're looking for, although it's helpful to know about parseTrainHelp as well, because changing the setUnitHelp might also change different areas of the game, such as what it says when you hover over a plot.

Edit: BTW, that's only if you mouse over to train a unit. There are other parse____Help and set____Help functions for buildings and projects, as well.
 
OK, a question to that theme: In some cases you can't build an improvement, but the button appears grayed out. Is there a possibility not to show these grayed out buttons?
 
Caesium said:
OK, a question to that theme: In some cases you can't build an improvement, but the button appears grayed out. Is there a possibility not to show these grayed out buttons?

For example, check out where they place the unit buttons in CvMainInterface.py, under the function updateSelectionFunction()...

Code:
# Units to construct
for i in range ( g_NumUnitClassInfos ):
	eLoopUnit = gc.getCivilizationInfo(pHeadSelectedCity.getCivilizationType()).getCivilizationUnits(i)

	if (pHeadSelectedCity.canTrain(eLoopUnit, False, True)): [b] # Note 1 #[/b]
		screen.appendMultiListButton( "BottomButtonContainer", gc.getUnitInfo(eLoopUnit).getButton(), iRow, WidgetTypes.WIDGET_TRAIN, i, -1, False )
		screen.show( "BottomButtonContainer" )
						
		if ( not pHeadSelectedCity.canTrain(eLoopUnit, False, False) ): [b]# Note 2 #[/b]
			screen.disableMultiListButton( "BottomButtonContainer", iRow, iCount, gc.getUnitInfo(eLoopUnit).getButton() )
						
		iCount = iCount + 1
		bFound = True

iCount = 0
if (bFound):
	iRow = iRow + 1
bFound = False

The first use of canTrain (note 1) uses the bVisible argument as True, meaning it's just checking visibility (can the person see this unit train icon?) The second time (note that the third argument is now false at Note 2) checks if the player can train this unit. If not, then this button should be greyed out.

To change this, you would probably want to call just one version of canTrain, using the bVisible flag as false before creating the button. Something like...

Code:
# Units to construct
for i in range ( g_NumUnitClassInfos ):
	eLoopUnit = gc.getCivilizationInfo(pHeadSelectedCity.getCivilizationType()).getCivilizationUnits(i)

	if (pHeadSelectedCity.canTrain(eLoopUnit, False, [b]False[/b])):  # Note 1 #
		screen.appendMultiListButton( "BottomButtonContainer", gc.getUnitInfo(eLoopUnit).getButton(), iRow, WidgetTypes.WIDGET_TRAIN, i, -1, False )
		screen.show( "BottomButtonContainer" )
						
		[s]if ( not pHeadSelectedCity.canTrain(eLoopUnit, False, False) ): [/s]
			[s]screen.disableMultiListButton( "BottomButtonContainer", iRow, iCount, gc.getUnitInfo(eLoopUnit).getButton() )[/s]
						
		iCount = iCount + 1
		bFound = True

iCount = 0
if (bFound):
	iRow = iRow + 1
bFound = False

Edit: I didn't test any of that code, but hopefully that helps you get started.
 
So Olleus were you thinking of making the mouseover of the Pillage button tell the Improvment to be Pillaged and perhaps even the Gold we will get for it. Heck why not let us SELECT what improvement to pillage!
 
Gerikes said:
For example, check out where they place the unit buttons in CvMainInterface.py, under the function updateSelectionFunction()...

Code:
# Units to construct
for i in range ( g_NumUnitClassInfos ):
	eLoopUnit = gc.getCivilizationInfo(pHeadSelectedCity.getCivilizationType()).getCivilizationUnits(i)

	if (pHeadSelectedCity.canTrain(eLoopUnit, False, True)): [b] # Note 1 #[/b]
		screen.appendMultiListButton( "BottomButtonContainer", gc.getUnitInfo(eLoopUnit).getButton(), iRow, WidgetTypes.WIDGET_TRAIN, i, -1, False )
		screen.show( "BottomButtonContainer" )
						
		if ( not pHeadSelectedCity.canTrain(eLoopUnit, False, False) ): [b]# Note 2 #[/b]
			screen.disableMultiListButton( "BottomButtonContainer", iRow, iCount, gc.getUnitInfo(eLoopUnit).getButton() )
						
		iCount = iCount + 1
		bFound = True

iCount = 0
if (bFound):
	iRow = iRow + 1
bFound = False

The first use of canTrain (note 1) uses the bVisible argument as True, meaning it's just checking visibility (can the person see this unit train icon?) The second time (note that the third argument is now false at Note 2) checks if the player can train this unit. If not, then this button should be greyed out.

To change this, you would probably want to call just one version of canTrain, using the bVisible flag as false before creating the button. Something like...

Code:
# Units to construct
for i in range ( g_NumUnitClassInfos ):
	eLoopUnit = gc.getCivilizationInfo(pHeadSelectedCity.getCivilizationType()).getCivilizationUnits(i)

	if (pHeadSelectedCity.canTrain(eLoopUnit, False, [b]False[/b])):  # Note 1 #
		screen.appendMultiListButton( "BottomButtonContainer", gc.getUnitInfo(eLoopUnit).getButton(), iRow, WidgetTypes.WIDGET_TRAIN, i, -1, False )
		screen.show( "BottomButtonContainer" )
						
		[s]if ( not pHeadSelectedCity.canTrain(eLoopUnit, False, False) ): [/s]
			[s]screen.disableMultiListButton( "BottomButtonContainer", iRow, iCount, gc.getUnitInfo(eLoopUnit).getButton() )[/s]
						
		iCount = iCount + 1
		bFound = True

iCount = 0
if (bFound):
	iRow = iRow + 1
bFound = False

Edit: I didn't test any of that code, but hopefully that helps you get started.
I don't have problems with units, only with the improvement build options of workers etc.
 
Caesium said:
I don't have problems with units, only with the improvement build options of workers etc.

Oh... my bad :P

In that case, it's a little more difficult. Unlike the cities, unit actions aren't seperated into easy unit/building/project/etc. definitions. Everything a unit can do, whether it's enter into the air bomb interface mode, build an improvement, found a city, nuke a territory, etc., is all clumped under the concept of performing an action. There are probably over 200 total actions in the game, although many of them are weeded out simply by the fact that they're not visible anyway (as is set in the XML). They are put on the screen using this code...


CvMainInterface.py (around lines 1368)..


Code:
self.setMinimapButtonVisibility(True)

if (CyInterface().getInterfaceMode() == InterfaceModeTypes.INTERFACEMODE_SELECTION):
			
	if ( pHeadSelectedUnit.getOwner() == gc.getGame().getActivePlayer() and g_pSelectedUnit != pHeadSelectedUnit ):
				
		g_pSelectedUnit = pHeadSelectedUnit
					
		iCount = 0

		actions = CyInterface().getActionsToShow()
		for i in actions:
			screen.appendMultiListButton( "BottomButtonContainer", gc.getActionInfo(i).getButton(), 0, WidgetTypes.WIDGET_ACTION, i, -1, False )
			screen.show( "BottomButtonContainer" )
				
			[b]if ( not CyInterface().canHandleAction(i, False) ):
				screen.disableMultiListButton( "BottomButtonContainer", 0, iCount, gc.getActionInfo(i).getButton() )[/b]
							
			if ( pHeadSelectedUnit.isActionRecommended(i) ):#or gc.getActionInfo(i).getCommandType() == CommandTypes.COMMAND_PROMOTION ):
				screen.enableMultiListPulse( "BottomButtonContainer", True, 0, iCount )
			else:
				screen.enableMultiListPulse( "BottomButtonContainer", False, 0, iCount )

			iCount = iCount + 1

		if (CyInterface().canCreateGroup()):
			screen.appendMultiListButton( "BottomButtonContainer", ArtFileMgr.getInterfaceArtInfo("INTERFACE_BUTTONS_CREATEGROUP").getPath(), 0, WidgetTypes.WIDGET_CREATE_GROUP, -1, -1, False )
					screen.show( "BottomButtonContainer" )
						
			iCount = iCount + 1

		if (CyInterface().canDeleteGroup()):
			screen.appendMultiListButton( "BottomButtonContainer", ArtFileMgr.getInterfaceArtInfo("INTERFACE_BUTTONS_SPLITGROUP").getPath(), 0, WidgetTypes.WIDGET_DELETE_GROUP, -1, -1, False )
			screen.show( "BottomButtonContainer" )
						

			iCount = iCount + 1

You can probably do a similar change as I did in the previous, where most of the code placing the button on the screen is actually put inside the block that checks if it's valid. Something like...

Code:
self.setMinimapButtonVisibility(True)

if (CyInterface().getInterfaceMode() == InterfaceModeTypes.INTERFACEMODE_SELECTION):
			
	if ( pHeadSelectedUnit.getOwner() == gc.getGame().getActivePlayer() and g_pSelectedUnit != pHeadSelectedUnit ):
				
		g_pSelectedUnit = pHeadSelectedUnit
					
		iCount = 0

		actions = CyInterface().getActionsToShow()
		for i in actions:
			[s]screen.appendMultiListButton( "BottomButtonContainer", gc.getActionInfo(i).getButton(), 0, WidgetTypes.WIDGET_ACTION, i, -1, False )[/s]
			[s]screen.show( "BottomButtonContainer" )[/s]
				
			if ( not CyInterface().canHandleAction(i, False) ):
				[s]screen.disableMultiListButton( "BottomButtonContainer", 0, iCount, gc.getActionInfo(i).getButton() )[/s]
				[b]screen.appendMultiListButton( "BottomButtonContainer", gc.getActionInfo(i).getButton(), 0, WidgetTypes.WIDGET_ACTION, i, -1, False )[/b]
				[b]screen.show( "BottomButtonContainer" )[/b]
							
[b]				# Begin indent
				if ( pHeadSelectedUnit.isActionRecommended(i) ):#or gc.getActionInfo(i).getCommandType() == CommandTypes.COMMAND_PROMOTION ):
					screen.enableMultiListPulse( "BottomButtonContainer", True, 0, iCount )
				else:
					screen.enableMultiListPulse( "BottomButtonContainer", False, 0, iCount )

				iCount = iCount + 1
				# End Indent[/b]

		if (CyInterface().canCreateGroup()):
			screen.appendMultiListButton( "BottomButtonContainer", ArtFileMgr.getInterfaceArtInfo("INTERFACE_BUTTONS_CREATEGROUP").getPath(), 0, WidgetTypes.WIDGET_CREATE_GROUP, -1, -1, False )
					screen.show( "BottomButtonContainer" )
						
			iCount = iCount + 1

		if (CyInterface().canDeleteGroup()):
			screen.appendMultiListButton( "BottomButtonContainer", ArtFileMgr.getInterfaceArtInfo("INTERFACE_BUTTONS_SPLITGROUP").getPath(), 0, WidgetTypes.WIDGET_DELETE_GROUP, -1, -1, False )
			screen.show( "BottomButtonContainer" )
						

			iCount = iCount + 1
 
This makes me think of stuff I could do in the TextManager such as create Text references under various XML objects and use them dynamicly.

So for example LeaderHeadInfo could have any number of <CivicDiplomacy> tags containing <CivicType>, <iDiplomacy> <bHas> and <TextTag> elements. The Leader in question would then like/dislike you depending on your current Civics and would say the taged text (easily tailored to the individual leader).

That would give a more SMAC like feel to the Diplomacy ware leaders REALY carred about specific civics rather then the watered down "do your civics happen to somewhat match my own right now" which isn't consistent or predictable.

I cant wait to have Stalin tell me "-5: Your capitalist freemarket economy will sell us the rope with which you will be hung"
 
Back
Top Bottom