New action buttons ONLY using SDK and XML

Pep

King
Joined
May 28, 2002
Messages
688
Location
Spain
I have been able to make new action buttons work only with SDK and XML (not using Python).

To make this posible, I have modified the following files:
- CIV4MissionInfos.xml (basic to show the new buttons on screen). IMPORTANT: It seems imperative to put the new defined mission at the bottom of the file to prevent crashes.
- CvEnums.h (C++ interface to Mission Types in CIV4MissionInfos.xml). IMPORTANT: Its imperative that the new defined missions be added at the bottom of the "enum DllExport MissionTypes" and in the SAME order as in the XML file.
- CvSelectionGroup.cpp (implement what the new actions do here).

Less important files (buttons MAY work if you don't touch them):
- CvGameCoreUtils.cpp (it seems an DLL interface. Don't know for sure).
- CyEnumsInterface.cpp (it seems an interface with Python. Don't know for sure).

Help files (XML): Put the help for the labels in CIV4MissionInfos.xml here.
- CIV4GameText_BTS.xml
- CIV4GameText_BTS_Fixed.xml

Optional: (Help files in my particular mod):
CvDLLWidgetData.cpp (time to heal for MISSION_HEAL is displayed here)
CvUnit.cpp (Lightning to the recommended actions here).

You can see the source code in my mod file (the mod contains several things. Just search "SENTRY_WHILE_HEAL" to see the code for the new action.

[EDITED] I have moved the attached file to the "Mod Components" forum:
http://forums.civfanatics.com/showthread.php?p=7432537#post7432537
 
Hey I followed all of your suggestions and everything I have done seems right, but I am getting this error message;

CvScreensInterface, line 705, in forceScreenRedraw
CvMainInterface, line 721, in redraw
CvMainInterface, line 1491, in updateSelectionButtons

RuntimeError: unidentifiable C++ exception

I am really new to all of this, so I don't quite know exactly what this means, but hopefully you can help me out. Basically I am giving a spy an assassination mission (ala SuperSpy mod by TrojanSheep) and this shows up when the spy goes into the same square as a rival unit (which is supposed to trigger the option of assassination).

Any help?
 
Hey I followed all of your suggestions and everything I have done seems right, but I am getting this error message;

CvScreensInterface, line 705, in forceScreenRedraw
CvMainInterface, line 721, in redraw
CvMainInterface, line 1491, in updateSelectionButtons

RuntimeError: unidentifiable C++ exception

I am really new to all of this, so I don't quite know exactly what this means, but hopefully you can help me out. Basically I am giving a spy an assassination mission (ala SuperSpy mod by TrojanSheep) and this shows up when the spy goes into the same square as a rival unit (which is supposed to trigger the option of assassination).

Any help?

I'm afraid I haven`t seen this error before. I followed the advices on this thread to compile my "mod":
http://forums.civfanatics.com/showthread.php?t=166933

Hope this helps.
 
may I request a button/mission? I'd like to see a found religion order. like how the tech discovers a religion i'd like a button that for a great prophet you push it and it opens the choose religion dialog (or the AI founds their preferred religion)

It seems a hard thing to do. Anyway, you can try to add your own order using the advices at this thread:
http://forums.civfanatics.com/showthread.php?t=166933

You can take my code and substitute one of my new orders for your proposed one, and change the appropiate C files to see it your idea works.
 
Damn it, it won't let me DL the SDK from the firaxis/2k games site. Is there anywhere else I can get this? I couldn't find it here at CF.
 
Basically my main problem right now is that nobody can identify the error I'm getting, or at least why I am getting it. I have tried to reinstall the mod again too and the same error pops up, and nobody seems to know why. I don't know much about SDK otherwise I'd fix it, but I'm trying to figure out why I can't get some action buttons to show up for a spy (this is from the superspies mod) that is supposed to be able to "assassinate" a lone unit, or "bribe" a lone unit.

When I play the mod I put it in no action buttons show up and I get a python error pop-up which freezes the game, no other python error pop-up I've had does this. This guy that's helping me with the mod said that it looks like its an SDK problem. I could post out exactly what it says is the issue though, in case you see something I'm missing.

The error says:

CvScreensInterface, line 705, in forceScreenRedraw
CvMainInterface, line 721, in redraw
CvMainInterface, line 1491, in updateSelectionButtons

RuntimeError: unidentifiable C++ exception


Now for the files. The CvScreensInterface.py file is NOT in my mod so I guess it would be using the vanilla BtS file. But here are lines 703 through 711 (including line 705 obviously):

Code:
	# Main Interface Screen
	if ( argsList[0] == MAIN_INTERFACE ):
		mainInterface.redraw()
	elif ( argsList[0] == WORLDBUILDER_SCREEN ):
		worldBuilderScreen.redraw()
	elif ( argsList[0] == WORLDBUILDER_DIPLOMACY_SCREEN ):
		worldBuilderDiplomacyScreen.redraw()
	elif ( argsList[0] == TECH_CHOOSER ):
		techChooser.updateTechRecords(true)

The next two lines are in the same file which is the CvmainInterface.py file, that I do have in my mod. The first error message refers to line 721, so here are line 720 through 723 in that file:

Code:
			# Selection Buttons Dirty
			self.updateSelectionButtons()
			CyInterface().setDirty(InterfaceDirtyBits.SelectionButtons_DIRTY_BIT, False)
		if ( CyInterface().isDirty(InterfaceDirtyBits.ResearchButtons_DIRTY_BIT) == True ):

And then in the same file it refers to line 1491. Here are lines 1489 through 1492:

Code:
					actions = CyInterface().getActionsToShow()
					for i in actions:
						screen.appendMultiListButton( "BottomButtonContainer", gc.getActionInfo(i).getButton(), 0, WidgetTypes.WIDGET_ACTION, i, -1, False )
						screen.show( "BottomButtonContainer" )

So that is all of the code that the python error refers to. Now remember it said, "Runtime Error: unidentifiable C++ exception" so because of this my friend said that it probably has to do with the SDK. But I don't know anything about that stuff. So basically I am hoping that it is just a python issue and can be fixed with python itself. Can anyone help me with this?
 
Go through each piece of line 1491 and make sure each one individually has the value that you expect it to have.
Code:
screen.appendMultiListButton( "BottomButtonContainer", gc.getActionInfo(i).getButton(), 0, WidgetTypes.WIDGET_ACTION, i, -1, False )
Make sure "BottomButtonContainer" refers to the right interface piece.
Make sure gc.getActionInfo(i).getButton() references the right path and that the file it references exists.
Make sure 0 is the proper listID
Make sure WidgetTypes.WIDGET_ACTION is the proper widget type
Make sure i makes sense as the (only) data argument for that widget type.
Make sure False is the proper bOption argument.

If I had to guess, I'd say the problem was related to gc.getActionInfo(i).getButton() since that's the easiest to mess up via a typo in the XML, but your general debugging approach should be to isolate the problem by breaking it up into pieces.

Also, since this code comes from the SuperSpies mod, have you installed that separately and verified that SuperSpies itself works OK? If so, go back over how you merged it into yours and make sure you didn't miss a step.
 
Wow, that sounds complicated, I don't know how to do any of that (or check it). The rest of the superspies works though, its just this action button that isn't working. I'll see if the guy I'm working with knows any of this stuff.

Thanks for the help though, hopefully I can figure it out.
 
It's not that complicated. It's basically just a combination of printing out variable contents and comparing them to the rest of your code. For example adding the line
Code:
print "ButtonPath for action %d is %s" %(i, gc.getActionInfo(i).getButton())
before the problem line will do one of two things.

1) it will either cause the crash to happen on this line instead of the other, which means the problem is that statement itself

2) it will leave a trail in the PythonDbg.log telling you exactly which action was causing the problem (it'd be the last entry) and telling you what the file path is. Then you can make sure that file exists and verify that the XML is setup properly.
 
Thanks for your help Dresden, I'll try that out tomorrow when I get home. But I think I'll try and get this guy who's helping me out (he's in England, so our times don't always match up for stuff like this all the time) to explain this to me step by step because I hate to admit I don't fully grasp this stuff. This is my first plunge into modding so a lot of this is "greek" to me. If I understand what you are saying correctly though is to add that line you told me to add ABOVE the line that says "screen.appendMultiListButton( "BottomButtonContainer", gc.getActionInfo(i).getButton(), 0, WidgetTypes.WIDGET_ACTION, i, -1, False )" and this will cause the crash to happen on this line?

But I was under the impression it is already occuring on this line (in this case 1491). Again, a lot of my questions may sound really stupid but I don't know anything about this stuff really.

So far the only python I've had to add involves adding the new inquisitor units (for my extra religions).
 
Go through each piece of line 1491 and make sure each one individually has the value that you expect it to have.
Code:
screen.appendMultiListButton( "BottomButtonContainer", gc.getActionInfo(i).getButton(), 0, WidgetTypes.WIDGET_ACTION, i, -1, False )
Make sure "BottomButtonContainer" refers to the right interface piece.
Make sure gc.getActionInfo(i).getButton() references the right path and that the file it references exists.
Make sure 0 is the proper listID
Make sure WidgetTypes.WIDGET_ACTION is the proper widget type
Make sure i makes sense as the (only) data argument for that widget type.
Make sure False is the proper bOption argument.

If I had to guess, I'd say the problem was related to gc.getActionInfo(i).getButton() since that's the easiest to mess up via a typo in the XML, but your general debugging approach should be to isolate the problem by breaking it up into pieces.

Also, since this code comes from the SuperSpies mod, have you installed that separately and verified that SuperSpies itself works OK? If so, go back over how you merged it into yours and make sure you didn't miss a step.

Actually I checked the superspies mod itself and that doesn't work either. So I think I merged it right, its just that the mod doesn't work. Its the same exact error for mine (of course the lines of code are differently numbered because my mod has extra code in it for the Inquisitors). When I ask in that thread I get responses like "I don't get a python error" (although they don't explain if they get the assassin button) and "well you probably did something wrong because Trojan Sheep is a great coder," which is nice for Trojan Sheep but not very helpful to me.

I just had an idea though; if you are right perhaps the XML is wrong, because I have Inquisitors in the game too, and these Inquisitors have a button for purging religion, and THAT button shows up. So I guess what I am asking is this; does this same Python code, (in this case the screen.appendMultiListButton( "BottomButtonContainer", gc.getActionInfo(i).getButton(), 0, WidgetTypes.WIDGET_ACTION, i, -1, False ) line) refer to anytime a button is used? If that is the case maybe I should compare the XML for both units and see if the actions are properly lineated or tagged to the right actions altogether. I don't know if this makes any sense to you, but maybe that is the road I should be taking here.
 
Okay, I did a little research on what comes with the spymod and in the CIV4MissionInfos.xml file the following shows up:

Code:
		<MissionInfo>
			<Type>MISSION_ASSASSIN</Type>
			<Description>TXT_KEY_MISSION_ASSASSIN</Description>
			<Help>TXT_KEY_MISSION_ASSASSIN_HELP</Help>
			<Waypoint>NONE</Waypoint>
			<EntityEventType>ENTITY_EVENT_GREAT_EVENT</EntityEventType>
			<iTime>14</iTime>
			<bTarget>0</bTarget>
			<bBuild>0</bBuild>
			<bSound>0</bSound>
			<HotKey/>
			<bAltDown>0</bAltDown>
			<bShiftDown>0</bShiftDown>
			<bCtrlDown>0</bCtrlDown>
			<iHotKeyPriority>0</iHotKeyPriority>
			<HotKeyAlt/>
			<bAltDownAlt>0</bAltDownAlt>
			<bShiftDownAlt>0</bShiftDownAlt>
			<bCtrlDownAlt>0</bCtrlDownAlt>
			<iHotKeyPriorityAlt>0</iHotKeyPriorityAlt>
			<bVisible>1</bVisible>
	<Button>,Art/Interface/Buttons/Actions/Assassinate.dds</Button>
		</MissionInfo>

I noticed that this does not occur in the Vanilla version, therefore it must have something to do with the Spymod itself and PROBABLY refers to the Assassin mission, although I could be wrong, but doubt it. Does this maybe help at all?
 
My friend told me it was probably in the SDK. So I looked through it and here are a few things.

This is in the CvDLLWidgetData.cpp file for the Assassin mission:

Code:
			//TSHEEP Assassin Mission
			else if (GC.getActionInfo(widgetDataStruct.m_iData1).getMissionType() == MISSION_ASSASSIN)
			{
				if(pMissionPlot->plotCount(PUF_isOtherTeam, pHeadSelectedUnit->getOwnerINLINE(), -1, NO_PLAYER, NO_TEAM, PUF_isVisible, pHeadSelectedUnit->getOwnerINLINE()) == 1)
				{
					CvUnit* pTargetUnit;
					int iEspionageCost = 0;
					int iMissionChance = 0;

					pTargetUnit = pMissionPlot->plotCheck(PUF_isOtherTeam, pHeadSelectedUnit->getOwnerINLINE(), -1, NO_PLAYER, NO_TEAM, PUF_isVisible, pHeadSelectedUnit->getOwnerINLINE());
					iEspionageCost = pHeadSelectedUnit->assassinCost(pTargetUnit);
					iMissionChance = pHeadSelectedUnit->assassinProb(pTargetUnit);
					szBuffer.append(NEWLINE);
					szBuffer.append(gDLL->getText("TXT_KEY_ACTION_ASSASSIN_MISSION",pTargetUnit->getNameKey(),iEspionageCost,iMissionChance));
				}
			}
			//TSHEEP End

Does this look right or no?
 
Also another thing; if I were to simply delete all of the code in the SDK files that refers to the assassin mission can I effectively remove it from my mod and thus no longer have/worry about this problem?

Or will that screw everything up?
 
Back
Top Bottom