1. We have added a Gift Upgrades feature that allows you to gift an account upgrade to another member, just in time for the holiday season. You can see the gift option when going to the Account Upgrades screen, or on any user profile screen.
    Dismiss Notice

HOW TO: Add Popups

Discussion in 'Civ4 - Modding Tutorials & Reference' started by Kael, Aug 21, 2006.

  1. Kael

    Kael Chieftain

    Joined:
    May 6, 2002
    Messages:
    17,401
    Location:
    Ohio
    Begin the Caffeine induced rambling

    [tab]Boom shaka laka, shaka laka, shaka laka Boom!

    [tab]If you a child of the 80's as I am you are probably wondering how you can combine your love for electronic wargaming and a certain MTV hit from way back, (when MTV actually played videos, yes I know kiddies, it sounds weird, but its true) Pop Up Video.

    [tab]The premise of the show was simple. That America's attention span had become so short, and we were so full of sugar, caffeine and less legal substances that we were unable to maintain the focus required to watch a whole 60 second rock video. Despite the fact that each scene flared with explosions, half naked women, loud music and enormous hair. We would find ourselves drifting off 15 seconds in and forgetting who the characters were and what was going on (hence the constant rock'n'roll chorus's to remind us).

    [tab]But MTV was wise, they invented popup videos to help. Now as we watched these videos we could learn interesting facts that occasionally had something to do with the video. Did you know that Jon "Cougar" Melancamp got his fancy middle name from the family gerbil? That Madonna used to not have a British accent? That Boy George sometime goes by the alias "Woodelf" when he is online? We learned all of these things from Pop Up Video.

    Now on to something coherent

    [tab]By now you are probably wondering how to bring this magic to your mod. Popups are surprisingly easy once they are understood. The type we are going to cover here allows us to present the player with a popup box with as many buttons as we want, and depending on the button they press a different python event kicks off:

    Code:
    1: def onGameStart(self, argsList):
    2:	'Called at the start of the game'
    3:	iPlayerNum = 0
    4:	for iPlayer in range(gc.getMAX_PLAYERS()):
    5:		player = gc.getPlayer(iPlayer)
    6:		if player.isAlive():
    7:			iPlayerNum = iPlayerNum + 1
    8:			if player.isHuman():
    9:				popupInfo = CyPopupInfo()
    10:				popupInfo.setButtonPopupType(ButtonPopupTypes.BUTTONPOPUP_PYTHON)
    11:				popupInfo.setText(CyTranslator().getText("TXT_KEY_POPUP_SELECT_TRAIT",()))
    12:				popupInfo.setData1(iPlayer)
    13:				popupInfo.setOnClickedPythonCallback("selectTrait")
    14:				popupInfo.addPythonButton(CyTranslator().getText("TXT_KEY_TRAIT_AGGRESSIVE", ()), "")
    15:				popupInfo.addPythonButton(CyTranslator().getText("TXT_KEY_TRAIT_CREATIVE", ()), "")
    16:				popupInfo.addPythonButton(CyTranslator().getText("TXT_KEY_TRAIT_EXPANSIVE", ()), "")
    17:				popupInfo.addPythonButton(CyTranslator().getText("TXT_KEY_TRAIT_FINANCIAL", ()), "")
    18:				popupInfo.addPythonButton(CyTranslator().getText("TXT_KEY_TRAIT_INDUSTRIOUS", ()), "")
    19:				popupInfo.addPythonButton(CyTranslator().getText("TXT_KEY_TRAIT_ORGANIZED", ()), "")
    20:				popupInfo.addPythonButton(CyTranslator().getText("TXT_KEY_TRAIT_PHILOSOPHICAL", ()), "")
    21:				popupInfo.addPythonButton(CyTranslator().getText("TXT_KEY_TRAIT_SPIRITUAL", ()), "")
    22:				popupInfo.addPopup(iPlayer) 
    
    [tab]Okay, lets walk through the above function. Lines 1-8 are the standard onGameStart function. Basically, isolating this to an event that occurs when the game begins and only for human players. You will want to make sure not to push popup's to AI players. If you want the AI to react to the same sorts of events you will need to follow your functions with an 'else:' on the 'isHuman()' or an 'if isHuman() == False:' and then call the python routines directly based on whatever logic you want the AI to use.

    [tab]Line 9: popupInfo = CyPopupInfo() declares the popupInfo object we are going to create and use. Its not much different than saying newUnit = pPlayer.initUnit(..), its just a definition of a new object. But by itself it doesn't do much, we need to define its characteristics.

    [tab]Line 10: popupInfo.setButtonPopupType() I honestly don't know how many ButtonPopupTypes there are, or what the differences between them are. BUTTONPOPUP_PYTHON is the one I always use and it works well.

    [tab]Line 11: popupInfo.setText() This is the body text for the popup window. In the example I'm running it through the translator so it can be localized in different languages but you could simply have: popupInfo.setText('Select your bonus Trait')

    [tab]Line 12: popupInfo.setData1() This is for any int data you want to pass to the python functions. You can have up to 4 data elements (setData1(), setData2(), setData3(), setData4()) defined in the popup and I will show you how we use them when we get to the events on the button presses.

    [tab]Line 13: popupInfo.setOnClickedPythonCallback() This is the python routine that is called when any button is pressed. Notice that the same python routine is called regardless of which button is pressed. I will show you when we declare the python event how to tell which button it was. The most important thing to remember with this is that the python routine must exist in the CvScreensInterface.py file.

    [tab]Line 14-21: popupInfo.addPythonButton() This is easy, it just adds a button for each line like this we have. The text that is included as the argument shows up on the button. As with the set text command above you could simply have: popupInfo.addPythonButton('Aggresive')

    [tab]Line 22: popupInfo.addPopup() The command that launches the popup. The argument here is the int value of the player that is supposed to receive it.

    [tab]Now let's look at the actual python event that it calls. Remember the following goes in the CvScreensInterface.py file:

    Code:
    def selectTrait(argsList):
    	iButtonId = argsList[0]
    	iData1 = argsList[1]
    	iData2 = argsList[2]
    	iData3 = argsList[3]
    	iData4 = argsList[4]
    	szText = argsList[5]
    	bOption1 = argsList[6]
    	bOption2 = argsList[7]
    
    	pPlayer = gc.getPlayer(iData)
    	iTrait = -1
    	if iButtonId == 0:
    		iTrait = gc.getInfoTypeForString('TRAIT_AGGRESSIVE')
    	if iButtonId == 1:
    		iTrait = gc.getInfoTypeForString('TRAIT_CREATIVE')
    	if iButtonId == 2:
    		iTrait = gc.getInfoTypeForString('TRAIT_EXPANSIVE')
    	if iButtonId == 3:
    		iTrait = gc.getInfoTypeForString('TRAIT_FINANCIAL')
    	if iButtonId == 4:
    		iTrait = gc.getInfoTypeForString('TRAIT_INDUSTRIOUS')
    	if iButtonId == 5:
    		iTrait = gc.getInfoTypeForString('TRAIT_ORGANIZED')
    	if iButtonId == 6:
    		iTrait = gc.getInfoTypeForString('TRAIT_PHILOSOPHICAL')
    	if iButtonId == 7:
    		iTrait = gc.getInfoTypeForString('TRAIT_SPIRITUAL')
    	if iTrait != -1:
    		pPlayer.addTrait(iTrait)
    
    [tab]Notice all of the arguments that are passed to the function by the popup. You can see where we breakout our Data1 – 4 elements and we could even pass a text string over and 2 boolens.

    [tab]The magic of figuring out what button the user pushed is that the first argument the popup passes to the python function is the number of the button. These are counted ordinally (starting with 0) so if you have 8 buttons you will have 0 – 7. With an if statements for each of the possible values of iButtonId we can run whatever python routines we want, or even send them off into other functions or other popups (oh, popups of popups, wouldn't MTV be proud).

    [tab]That’s it, nothing too complicated with the process. But I would expect you might have a few questions I'll try to answer here:

    1. pPlayer.addTrait(), whats that?

    [tab]Very observant of you, man who types exactly like me. That cool little function is from TheLopez's Scriptable Leader Traits modpack. It is very cool, check it out if you have a chance.

    2. Besides adding traits to players with TheLopez's mudpack what can we do with this?

    [tab]Anything you can do with python. Want to give the player an option when he captures a city or defeats a special unit, this is how you do it. Want to give them a list of options to deal with revolting peasants or the ability to share the secrets of the alternative fuel source or keep it (and their oil monopoly) to themselves? The sky is the limit.

    3. This is all well and good, but shouldn't your function check for <insert thing I forgot to do>?

    [tab]Probably. And I did really simplify my code to make it easy for beginning programmers (ie: me) to understand. There are quite a few checks but they aren't nessesary to understand popups and I thought they would just confuse the guide. If you really want to see what the real code looks like it is below:

    Spoiler :

    Code:
    def onGameStart(self, argsList):
    	'Called at the start of the game'
    	iPlayerNum = 0
    	for iPlayer in range(gc.getMAX_PLAYERS()):
    		player = gc.getPlayer(iPlayer)
    		if player.isAlive():
    			iPlayerNum = iPlayerNum + 1
    			if player.hasTrait(gc.getInfoTypeForString('TRAIT_ADAPTIVE')):
    				if player.isHuman():
    					popupInfo = CyPopupInfo()
    					popupInfo.setButtonPopupType(ButtonPopupTypes.BUTTONPOPUP_PYTHON)
    					popupInfo.setText(CyTranslator().getText("TXT_KEY_POPUP_SELECT_TRAIT",()))
    					popupInfo.setData1(iPlayer)
    					popupInfo.setOnClickedPythonCallback("selectTrait")
    					szText = CyTranslator().getText("TXT_KEY_TRAIT_AGGRESSIVE", ())
    					if player.hasTrait(gc.getInfoTypeForString('TRAIT_AGGRESSIVE')):
    						szText = szText + CyTranslator().getText("TXT_KEY_TRAIT_ALREADY_KNOWN", ())
    					popupInfo.addPythonButton(szText, "")
    					szText = CyTranslator().getText("TXT_KEY_TRAIT_ARCANE", ())
    					if player.hasTrait(gc.getInfoTypeForString('TRAIT_ARCANE')):
    						szText = szText + CyTranslator().getText("TXT_KEY_TRAIT_ALREADY_KNOWN", ())
    					popupInfo.addPythonButton(szText, "")
    					szText = CyTranslator().getText("TXT_KEY_TRAIT_CREATIVE", ())
    					if player.hasTrait(gc.getInfoTypeForString('TRAIT_CREATIVE')):
    						szText = szText + CyTranslator().getText("TXT_KEY_TRAIT_ALREADY_KNOWN", ())
    					popupInfo.addPythonButton(szText, "")
    					szText = CyTranslator().getText("TXT_KEY_TRAIT_DEFENDER", ())
    					if player.hasTrait(gc.getInfoTypeForString('TRAIT_DEFENDER')):
    						szText = szText + CyTranslator().getText("TXT_KEY_TRAIT_ALREADY_KNOWN", ())
    					popupInfo.addPythonButton(szText, "")
    					szText = CyTranslator().getText("TXT_KEY_TRAIT_EXPANSIVE", ())
    					if player.hasTrait(gc.getInfoTypeForString('TRAIT_EXPANSIVE')):
    						szText = szText + CyTranslator().getText("TXT_KEY_TRAIT_ALREADY_KNOWN", ())
    					popupInfo.addPythonButton(szText, "")
    					szText = CyTranslator().getText("TXT_KEY_TRAIT_FINANCIAL", ())
    					if player.hasTrait(gc.getInfoTypeForString('TRAIT_FINANCIAL')):
    						szText = szText + CyTranslator().getText("TXT_KEY_TRAIT_ALREADY_KNOWN", ())
    					popupInfo.addPythonButton(szText, "")
    					szText = CyTranslator().getText("TXT_KEY_TRAIT_INDUSTRIOUS", ())
    					if player.hasTrait(gc.getInfoTypeForString('TRAIT_INDUSTRIOUS')):
    						szText = szText + CyTranslator().getText("TXT_KEY_TRAIT_ALREADY_KNOWN", ())
    					popupInfo.addPythonButton(szText, "")
    					szText = CyTranslator().getText("TXT_KEY_TRAIT_ORGANIZED", ())
    					if player.hasTrait(gc.getInfoTypeForString('TRAIT_ORGANIZED')):
    						szText = szText + CyTranslator().getText("TXT_KEY_TRAIT_ALREADY_KNOWN", ())
    					popupInfo.addPythonButton(szText, "")
    					szText = CyTranslator().getText("TXT_KEY_TRAIT_MAGIC_RESISTANT", ())
    					if player.hasTrait(gc.getInfoTypeForString('TRAIT_MAGIC_RESISTANT')):
    						szText = szText + CyTranslator().getText("TXT_KEY_TRAIT_ALREADY_KNOWN", ())
    					popupInfo.addPythonButton(szText, "")
    					szText = CyTranslator().getText("TXT_KEY_TRAIT_PHILOSOPHICAL", ())
    					if player.hasTrait(gc.getInfoTypeForString('TRAIT_PHILOSOPHICAL')):
    						szText = szText + CyTranslator().getText("TXT_KEY_TRAIT_ALREADY_KNOWN", ())
    					popupInfo.addPythonButton(szText, "")
    					szText = CyTranslator().getText("TXT_KEY_TRAIT_RAIDERS", ())
    					if player.hasTrait(gc.getInfoTypeForString('TRAIT_RAIDERS')):
    						szText = szText + CyTranslator().getText("TXT_KEY_TRAIT_ALREADY_KNOWN", ())
    					popupInfo.addPythonButton(szText, "")
    					szText = CyTranslator().getText("TXT_KEY_TRAIT_SPIRITUAL", ())
    					if player.hasTrait(gc.getInfoTypeForString('TRAIT_SPIRITUAL')):
    						szText = szText + CyTranslator().getText("TXT_KEY_TRAIT_ALREADY_KNOWN", ())
    					popupInfo.addPythonButton(szText, "")
    					popupInfo.addPopup(iPlayer)
    				else:
    					if player.getLeaderType() == gc.getInfoTypeForString('LEADER_VARN'):
    						player.addTrait(gc.getInfoTypeForString('TRAIT_FINANCIAL'))
    					if player.getLeaderType() == gc.getInfoTypeForString('LEADER_CARDITH'):
    						player.addTrait(gc.getInfoTypeForString('TRAIT_PHILOSOPHICAL'))
    					if player.getLeaderType() == gc.getInfoTypeForString('LEADER_CASSIEL'):
    						player.addTrait(gc.getInfoTypeForString('TRAIT_INDUSTRIOUS'))
    					if player.getLeaderType() == gc.getInfoTypeForString('LEADER_SHEELBA'):
    						player.addTrait(gc.getInfoTypeForString('TRAIT_MAGIC_RESISTANT'))
    					if player.getLeaderType() == gc.getInfoTypeForString('LEADER_JONUS'):
    						player.addTrait(gc.getInfoTypeForString('TRAIT_EXPANSIVE'))
    
     

    Attached Files:

  2. strategyonly

    strategyonly C2C Supreme Commander

    Joined:
    Mar 13, 2006
    Messages:
    20,407
    Gender:
    Male
    Location:
    MN
    Great idea, thx. and thx for the good examples, i am not much of a reader.
     
  3. wotan321

    wotan321 Chieftain

    Joined:
    Oct 25, 2001
    Messages:
    1,218
    Location:
    NC, USA
    Great stuff! Thanks.
     
  4. woodelf

    woodelf Bard

    Joined:
    Jun 12, 2003
    Messages:
    15,036
    Location:
    Gallery
    I think VH1 did the pop-up video first, but I could be wrong. :p

    Great write-up Kael.
     
  5. Jeckel

    Jeckel Great Reverend

    Joined:
    Nov 16, 2005
    Messages:
    1,637
    Location:
    Peoria, IL
    Very informative Kael, that gives me the courage to takle puting popups in a few of my mods. Could you perhaps explain a little how to add in some subwindow wigets that display information, like TheLopez's Nuke Manager or Teg's Unit Statistics screen? Nothing to complex, just how to put widgets inside widgets and text/icons in those.

    Again, thanx bunches for this. :)
     
  6. Kael

    Kael Chieftain

    Joined:
    May 6, 2002
    Messages:
    17,401
    Location:
    Ohio
    I haven't looked at those mods, but I suspect they are using screens, not popups for them. Designing a screen is cool and offers a lot of unctionality but is significantly more complex than a popup.
     
  7. Civmansam

    Civmansam Chieftain

    Joined:
    Jan 15, 2006
    Messages:
    909
    Extremely useful writeup Kael! :thumbsup: This will help a bunch of people. Thank you for all these tutorials to help less experienced modders like me
     
  8. Kael

    Kael Chieftain

    Joined:
    May 6, 2002
    Messages:
    17,401
    Location:
    Ohio
    I added a screenshot to give an example of what can be done.
     
  9. Civmansam

    Civmansam Chieftain

    Joined:
    Jan 15, 2006
    Messages:
    909
    I really need to use that popup :rotfl:
     
  10. Gerikes

    Gerikes User of Run-on Sentences.

    Joined:
    Jul 26, 2005
    Messages:
    1,753
    Location:
    Massachusetts
    For informational sake, here are the different popup types:

    BUTTONPOPUP_TEXT,
    BUTTONPOPUP_MAIN_MENU,
    BUTTONPOPUP_CONFIRM_MENU,
    BUTTONPOPUP_DECLAREWARMOVE,
    BUTTONPOPUP_CONFIRMCOMMAND,
    BUTTONPOPUP_LOADUNIT,
    BUTTONPOPUP_CHOOSETECH,
    BUTTONPOPUP_RAZECITY,
    BUTTONPOPUP_DISBANDCITY,
    BUTTONPOPUP_CHOOSEPRODUCTION,
    BUTTONPOPUP_CHANGECIVIC,
    BUTTONPOPUP_CHANGERELIGION,
    BUTTONPOPUP_CHOOSEELECTION,
    BUTTONPOPUP_DIPLOVOTE,
    BUTTONPOPUP_DIPLOVOTE_RESULTS,
    BUTTONPOPUP_ALARM,
    BUTTONPOPUP_DEAL_CANCELED,
    BUTTONPOPUP_PYTHON,
    BUTTONPOPUP_PYTHON_SCREEN,
    BUTTONPOPUP_DETAILS,
    BUTTONPOPUP_ADMIN,
    BUTTONPOPUP_ADMIN_PASSWORD,
    BUTTONPOPUP_EXTENDED_GAME,
    BUTTONPOPUP_DIPLOMACY,
    BUTTONPOPUP_ADDBUDDY,
    BUTTONPOPUP_FORCED_DISCONNECT,
    BUTTONPOPUP_PITBOSS_DISCONNECT,
    BUTTONPOPUP_KICKED,

    NUM_BUTTONPOPUP_TYPES

    Many of what they are, how they're created, and how they work are dealt with in the SDK ( see CvDllButtonPopup.cpp more what they do). However, the python one will take all the information and pass it to python. That's why you should really only use the python one unless you're creating all that in the SDK.

    In CvDLLButtonPopup::OnOkClicked...
    Spoiler :

    Code:
    case BUTTONPOPUP_PYTHON:
    		if (!info.getOnClickedPythonCallback().IsEmpty())
    		{
    			CyArgsList argsList;
    			argsList.add(pPopupReturn->getButtonClicked());
    			argsList.add(info.getData1());
    			argsList.add(info.getData2());
    			argsList.add(info.getData3());
    			argsList.add(info.getFlags());
    			argsList.add(info.getText());
    			argsList.add(info.getOption1());
    			argsList.add(info.getOption2());
    			gDLL->getPythonIFace()->callFunction(PYScreensModule, info.getOnClickedPythonCallback(), argsList.makeFunctionArgs());
    			break;
    		}
    		break;
    


    In CvDLLButtonPopup::OnFocus...
    Spoiler :

    Code:
    case BUTTONPOPUP_PYTHON:
    case BUTTONPOPUP_PYTHON_SCREEN:
    		if (!info.getOnFocusPythonCallback().IsEmpty())
    		{
    			long iResult;
    			CyArgsList argsList;
    			argsList.add(info.getData1());
    			argsList.add(info.getData2());
    			argsList.add(info.getData3());
    			argsList.add(info.getFlags());
    			argsList.add(info.getText());
    			argsList.add(info.getOption1());
    			argsList.add(info.getOption2());
    			gDLL->getPythonIFace()->callFunction(PYScreensModule, info.getOnFocusPythonCallback(), argsList.makeFunctionArgs(), &iResult);
    			if (0 != iResult)
    			{
    				gDLL->getInterfaceIFace()->popupSetAsCancelled(pPopup);
    			}
    		}
    		break;
    	}
    


    The code that launches your popup...

    Spoiler :

    Code:
    bool CvDLLButtonPopup::launchPythonPopup(CvPopup* pPopup, CvPopupInfo &info)
    {
    	gDLL->getInterfaceIFace()->popupSetBodyString(pPopup, info.getText());
    	for (int i = 0; i < info.getNumPythonButtons(); i++)
    	{
    		gDLL->getInterfaceIFace()->popupAddGenericButton(pPopup, info.getPythonButtonText(i), info.getPythonButtonArt(i).IsEmpty() ? NULL : info.getPythonButtonArt(i).GetCString());
    	}
    
    	gDLL->getInterfaceIFace()->popupSetPopupType(pPopup, POPUPEVENT_WARNING, ARTFILEMGR.getInterfaceArtInfo("INTERFACE_POPUPBUTTON_WARNING")->getPath());
    	gDLL->getInterfaceIFace()->popupLaunch(pPopup, false, POPUPSTATE_IMMEDIATE);
    
    	return (true);
    }
    


    What I find most interesting about all of this is that you can create a screen and have it work like a popup, as I saw in this SDK snippet...

    Code:
    bool CvDLLButtonPopup::launchPythonScreen(CvPopup* pPopup, CvPopupInfo &info)
    {
    	// this is not really a popup, but a Python screen
    	// we trick the app into thinking that it's a popup so that we can take advantage of the popup queuing system 
    
    	CyArgsList argsList;
    	argsList.add(info.getData1());
    	argsList.add(info.getData2());
    	argsList.add(info.getData3());
    	argsList.add(info.getOption1());
    	argsList.add(info.getOption2());
    	gDLL->getPythonIFace()->callFunction(PYScreensModule, CvString(info.getText()).GetCString(), argsList.makeFunctionArgs());
    
    	return (false); // return false, so the Popup object is deleted, since it's just a dummy
    }
    
    I've never tried it, but it could prove useful to someone who wants to make something like a popup but have it be a screen to use all the advanced screen widgets.
     
  11. ocedius

    ocedius C++ induced baldness

    Joined:
    Jun 27, 2003
    Messages:
    617
    Location:
    TX and proud of it!
    Holy :eek: I can't believe I missed this. Thanks Kael. And you too Gerikes.
     
  12. wotan321

    wotan321 Chieftain

    Joined:
    Oct 25, 2001
    Messages:
    1,218
    Location:
    NC, USA
    So, what code is needed in the CvEventManager.py file to have a simple textbox popup show up on a certain turn announcing something like "Enemy reinforcements have arrived"? I've looked at examples, and its done in about as many ways as there are people to do mods. I am new to python and would love some education on this.

    What I want, exactly, is that on a certain turn, a textbox shows up on the screen with my text in it, and you have to click on the OK button to move on.

    Thanks.
     
  13. Gunner

    Gunner Chieftain

    Joined:
    Aug 21, 2004
    Messages:
    1,389
    Location:
    Goochland, VA
    Hey thanks a lot for this Kael! I can't believe I hadn't noticed it till now.
     
  14. Kael

    Kael Chieftain

    Joined:
    May 6, 2002
    Messages:
    17,401
    Location:
    Ohio
    OKay, this is going to be a bit confusing becasue Im going to use a different kind of popup then the one I used above. The one above is for an option box, allowing the player to make a selection and then kicking off a pythong routine depending on which selection they pick. For what you want there is a much easier method.

    Code:
    	def onBeginGameTurn(self, argsList):
    		'Called at the beginning of the end of each turn'
    		iGameTurn = argsList[0]
    
    		if iGameTurn == 75:
    			szTitle = self.szGameDate = CyGameTextMgr().getTimeStr(CyGame().getGameTurn(), false)
    			popup = PyPopup.PyPopup(-1)
    			popup.addDDS('art/interface/popups/chocolate.dds', 0, 0, 128, 384)
    			popup.addSeparator()
    			popup.setHeaderString(szTitle)
    			popup.setBodyString('Your units yearn for the chocolatey goodness hersey bar.  You should research Flavored Plastic and Nuggets as soon as possible.')
    			popup.launch(true, PopupStates.POPUPSTATE_QUEUED)
    
    Okay, this an extremly simple popup. It only gives the option to click okay and it will be presented to all players.

    The really cool thing about this kind of popup is it is the only sort that I know how to include a picture with (pictures are cool). The addDDS function points to the location of the DDS file, the X coordinate, the Y coordinate, the Height and the Width of the picture (in that order).

    There is a lot of things you should probably do to make that popup more functions (run the text through the localization translator, have the turn modified by the gamespeed, etc) but I wanted to provide as simple an example as possible.
     
  15. wotan321

    wotan321 Chieftain

    Joined:
    Oct 25, 2001
    Messages:
    1,218
    Location:
    NC, USA
    Fantastic! Thanks. I know there are a lot of noob modders (like me) who are going to benefit greatly from this.
     
  16. Kael

    Kael Chieftain

    Joined:
    May 6, 2002
    Messages:
    17,401
    Location:
    Ohio
    We all benefit. With no documentation the first person to go through this kind of stuff has to spend hours figuring it out. But hopefully we can share whatever we learn to make it faster for everyone else.
     
  17. Jeckel

    Jeckel Great Reverend

    Joined:
    Nov 16, 2005
    Messages:
    1,637
    Location:
    Peoria, IL
    Hey Kael, in the OP could you put some code tags around the code in the spoiler? No hurry, but it is a little confusing without the spacing in there. :)
     
  18. Kael

    Kael Chieftain

    Joined:
    May 6, 2002
    Messages:
    17,401
    Location:
    Ohio
    Done, thanks.
     
  19. Fabrysse

    Fabrysse Charming-snake learner

    Joined:
    Sep 11, 2006
    Messages:
    430
    Location:
    Toulouse - France
    Please,
    What code should I add to have checkboxes and radio bottuns in a popup ?
    And how will I get results in my function ?
     
  20. Kael

    Kael Chieftain

    Joined:
    May 6, 2002
    Messages:
    17,401
    Location:
    Ohio
    There is no way to add checkboxes or radio buttons through the CyPopupInfo control that I used the following are all of the python commands available for CyPopupInfo:

    If you want to make something more complex than this you will need to design a screen to do it similiar to the civics screen, religion screen, etc. Checking out the code on those objects should help you get started.
     

Share This Page