• 0

    posted a message on Pokemon-style game with SC2 Units + Full Banking
    Quote from sigmapl: Go

    Someone on /r/starcraft just found this project's video on YT and the post is currently top4.

    Talk about pressure

    Yeah, I noticed when my video got 30+ comments and jumped 15,000 views all within 24 hours. I was wondering where it came from. Thanks for letting me know.

    I'd be lying if I said it hasn't gotten me thinking about this project again...

    I'm going to follow up this video with a much newer one in the next day or two. Where I go from there... has yet to be determined.

    -Jamin

    Posted in: Project Workplace
  • 0

    posted a message on Pokemon-style game with SC2 Units + Full Banking

    @DrSuperEvil: Go

    It's actually much further along than that.

    Posted in: Project Workplace
  • 0

    posted a message on Pokemon-style game with SC2 Units + Full Banking

    @DrSuperEvil: Go

    I don't know. I'm not going to make any promises I can't keep, so...

    Progress has been pretty slow as of late, as I have lots of other things going on in my life, but there has been some progress. I have a working damage system with stats and it even checks for type effectiveness. There's levels but no experience yet, so that will probably happen next.

    I'm happy to be back in the swing of things, but I can't promise that will stick. As I said, there's a lot of other things going on in my life: I work 40+ hours a week, I'm currently taking 2 classes, have a girlfriend as well as friends I like to hang out with, as well as normal life stuff.

    I'll see where things go, but hopefully something will come out eventually. As always, I'll accept help in any form it comes. Any help will definitely speed up the process, and may even get me more excited about the project. In all honesty, I got kind of un-excited about this project, but I never considered dropping it. I just needed to step away for some time and focus on some more important things in my life before I could again refocus on this project. I definitely want to see this project to fruition, but I don't know how long that will be.

    I've considered releasing a "pre-alpha demo" once general combat with experience is working. It may be fun to wander around the small area, level up, and collect what pokemon there are. At the same time, I know people get disheartened by "always in beta" projects, and start demanding/desiring updates, most likely at a faster pace than I can deliver. I don't want to kill the project by releasing something too early. Let me know what you guys think.

    Posted in: Project Workplace
  • 0

    posted a message on Pokemon-style game with SC2 Units + Full Banking

    @TacoManStan: Go

    The player model is a civilian, made short and stout. They actually look pretty good, and you get to choose between 6 male or 6 female models. I've intentionally avoided trying to reproduce any copyright models or characters. This game will be based on SC2 units and models, not pokemon.

    Posted in: Project Workplace
  • 0

    posted a message on Important Model Needed for the Betterment of the Community!

    ZOMG! This is epic! Thanks much for your help!

    To all map developers: easter egg the hell out of this!

    Posted in: Artist Tavern
  • 0

    posted a message on Important Model Needed for the Betterment of the Community!

    Kittyloaf

    That's right, Kittyloaf! I would absolute love to see this as a critter in a game. So if anyone is daring enough to take it on, I will <3 you forever. Plus, you can share it with the community and it can become our own community easter egg/meme.

    As far as animations go, I'm not sure what capability there is. At the very least having some motion while staning still would be preferred. If there's some way he can walk around, be it walking, bouncing, whatever, that would be even better.

    Posted in: Artist Tavern
  • 0

    posted a message on Incident with irc user on sc2mapster (mini rant)

    @FuzzYD: Go

    I put records inside of records all the time. It's declared just like any other record (a record is a variable), but inside of another record.

    What you can't do is make a circular reference. You can not put a record inside of itself. For example, if you were making some like a linked list or tree data structure, you might make a "Node" record, and want to store other Nodes inside of it. You can't do that. The GUI simply won't let you. You can "work around" this by making a second record to hold the first, but the cicular reference will crash the game.

    That said, my game has some highly nested records. Some of them run like 4-5 records deep. It's a great way to organize data. I just wish we could use pointers to reference them...

    Posted in: General Chat
  • 0

    posted a message on Pokemon-style game with SC2 Units + Full Banking
    Quote from Dragenrder: Go

    hmm noones here anymore :(

    I did take a hiatus. I had some personal stuff going on in my life that required my attention and forced me to refocus my priorities.

    Having gone through that, I have very recently returned to mapping. My time is more limited than it was before, but I really like mapping and it's a fun hobby that I want to keep around. Therefore, I will continue to find time for it.

    Currently, I'm working on stats. I've got a working set of stats, and I'm building the systems to calculate damage and such based on these stats. Right now, the system is very tightly based on the actual Pokemon stat system. Once I have that groundwork down, I may start making decisions to deviate from this model. For now though, the way that the real Pokemon games calculate damage is exactly how Pocket Warriors calculates damage.

    I will be doing most of my work offline. That is to say, I won't be posting a lot in the forums, I won't be on IRC a lot, and I won't be posting any tutorials for a while. These are distractions that I just don't have time for at this point in my life.

    Posted in: Project Workplace
  • 0

    posted a message on NA Map Nights

    This week will be my last week as host of map night. :( My life has turned crazy-busy and I can no longer make the commitment to host map night every Friday night. Hopefully someone else will step in so that Friday night can continue unabated. In fact, someone might be capable of setting up a better stream than I had and/or have more time to post the VODs, and perhaps map night will be stronger than ever.

    I will still join when I can, I just can't host any longer.

    Posted in: General Chat
  • 0

    posted a message on Center Dialog Label Text

    Centering dialog item text is definitely possible. You have to use "Set Dialog Item Style". "Text with Style" or using inline style tags does not work; the dialog item will ignore the alignment.

    You'll also need a font style with a center alignment. I recommend setting up a custom style.

    I've covered all of this in quite some detail here: http://forums.sc2mapster.com/resources/tutorials/17978-dialogs-really-great-looking-dialogs-part-2/

    Posted in: Triggers
  • 0

    posted a message on [Dialogs] Really Great Looking Dialogs, Part 3

    [Reserved]

    Posted in: Tutorials
  • 0

    posted a message on [Dialogs] Really Great Looking Dialogs, Part 3

    Alternate Controls and Multi-User Dialogs

    Introduction

    In parts 1 and 2 in this series, we used only three different dialog item types: buttons, images, and labels. While most dialogs will only ever use these controls, occassionally the need for other control types comes up. Galaxy editor has a number of dialogs controls to choose from, but we'll start with just one and add more as we go on. For now, we're going to focus on the edit box.

    Also, the dialogs in the previous tutorials always showed the same thing to all players. This works great for an introductory demonstation, but very few real-world examples behave like this. In reality, you'll often want to show dialogs to different players at different times, and some times the same dialog will even look wildly different. We'll explore one way you can show different information to different players using the same dialog.

    To demonstrate this, we'll be building a general-purpose edit box dialog. We'll start with the map from part 2. We won't be using the Unit Selection Dialog directly, but we will be using the same dialog constants for consistancy. We'll also be using the custom styles from part 2, and we'll be adding some more.

    The map for part 3 will be built on top of the tutorial map from part 2. If you do not already have the tutorial map for part 2, and you want to follow through this tutorial, I suggest you go back to part 2 and download the map attachment now.

    Multi-User Dialogs

    Choosing When a User Sees a Dialog

    In parts 1 and 2, we created and displayed the dialog in a single step. Since the dialog was being displayed at the beginning of the game, and only once, this worked great. This would work no matter when we wanted to show the dialog, so long as we only wanted to show it once. If we wanted to show the same dialog more than once, however, this doesn't work so well.

    Specifically, using this method can create problems if you accidently display the same dialog twice at the same time. If we create the dialog new each time, and save the dialog into the same variable, we lose the first dialog when we create a second. If this first dialog isn't hidden or destroyed before this happens, it will never go away and will constantly block the players vision. We obviously don't want this. We could possibly get around this by destroying the old dialog before creating a new one, but this doesn't work if we're using the same dialog for multiple players.

    The easiest way to do this is to break up creating and showing the dialog into two different steps. We can create the dialog at the very beginning of the game, and then just not show it. Then, you can call the Show Dialog function whenever you need a user to see the dialog. What's more, you can show a dialog for only one player (or multiples), so breaking this apart gives us some additional flexibility.

    These days, every dialog I create has at least 3 action definitions, "Create", "Show", and "Hide". Create is always called at the beginning of the game. In fact, I have one action called "Dialog Initialization" that is called from the Melee Initialization trigger, that calls all of the dialog create actions. You could call the "Show/Hide Dialog" directly from your code, but often showing or hiding a dialog requires more than one step. Even if it doesn't, you may add functionality in the future, and using an action to show/hide your dialog will keep you from having to change code in more than one place. I recommend using show/hide action definitions for all dialogs, even if the action definition is only one line long.

    Showing Different Things to Different Players

    Dialogs in GE are actually incredibly customizeable on a per-player basis. There is a lot you can do without having to create a seperate dialog for each player. With only a few exceptions, almost all of the dialog functions have a player group parameter. This means you can show and hide dialog controls, change the image for an image control, change the value of a edit or list control, even resize or move controls, all for one player only. If this doesn't make a lot of sense yet, don't worry. We'll be showing concrete examples as we move forward.

    There are a couple of noteable exceptions to this, and they are a little unfortunate: you can not move or resize a dialog on a per-player basis. You can move or resize dialog items, but you can't move or resize the dialog itself. There a couple of ways around this, the easiest is to just create a seperate dialog for each player. We will not be covering how to do that in this tutorial. This tutorial will focus on using one dialog for all players, but customizing the content of the dialog to fit the player. Actually using a seperate dialog for each player will be the topic of another tutorial; it is the exception, not the rule.

    Getting Started

    Before we get started, let's lay a little groundwork. Preparation and planning actually compose a very large percentage of development time, but this time is usually paid back several times when it takes less time to develop and maintain a project. This is why I have focused on planning through all of these tutorials.

    Center Function

    Before we move too far, I'd like to share a useful utility function with you. In part 1, we did a calculation to center objects that looked something like this: (cButtonSize / 2) - (cIcon Size / 2), or in more general terms: (Total Width / 2) - (Item Width / 2). It's not a very complicated calculation, but it can be a hassle to put this into the GUI every time we need to use it (and we will be using it several times). To avoid having to do this over and over, we'll create a simple function.

    This will be the first actual function will have created in these tutorials. I more-or-less accidently use the terms "action definition" and "function" interchangeably because in other programming languages there is no difference between the two, and they are both typically called "functions". In GE, however, there are a few discrete differences between action definitions and functions. The only really noteworthy difference (for now at least), is that a function can return a value. That is, when you call a function you actually get a value back. In our case, this will be the end-result of our calculation.

    So let's take a look at the Center function:

    Center
        Options: Function
        Return Type: Integer
        Parameters
            total width = 0 <Integer>
            item width = 0 <Integer>
        Grammar Text: Center(total width, item width)
        Hint Text: (None)
        Custom Script Code
        Local Variables
        Actions
            General - Return ((total width / 2) - (item width / 2))
    

    Center

    For now, I put this function at the root. We can always move it later. As you end up creating more functions like this, you might end up with a folder called "Functions". Eventually, they might end up being grouped by type.

    More Constants

    Our dialog is going to have standard "OK" and "Cancel" buttons at the bottom of it, so let's create a few constants to describe the size of these buttons, as well as the gap between the other dialog items and these buttons:

                    cDialog Button Gap = 20 <Integer (Constant)>
                    cDialog Button Height = 60 <Integer (Constant)>
                    cDialog Button Width = 200 <Integer (Constant)>
    

    We're also going to end up with some constants that are specific to the dialogs that we are creating. We could put these constants with the dialog itself, but I find it's better to keep all your dialog constants in one place. Also, although unlikely, it is possible that you will want to use that constant for something else. For organization purposes, I put them in seperate folders inside the Dialog Constants folder. As an example, create a folder called "Edit Box", and create the following two constants inside of it:

                    cEdit Box Width = 450 <Integer (Constant)>
                    cEdit Box Height = 60 <Integer (Constant)>
    

    We will use these constants shortly to build a simple edit box dialog. If we decided to create a dialog with another edit box later, we might use these constants to establish consistancy, or we might not depending on the circumstances and size of the dialog.

    As one final step, to avoid confusion, I've decided to rename "Button Size" and "Button Gap" to "Icon Button Size" and "Icon Button Gap", respectively. Your Dialog Constants folder should now look something like this:

    Dialog Constants

    More Styles

    We established standard and header styles in part 2, but that's not going to be enough any more. Really, we want to assign a seperate style to each type of item we will be using on our dialogs. Even if the fonts end up being the same (as will be the case), we want seperate styles so that we can change them seperately if need be. This will be our new customstyles.sc2style file:

    <StyleFile>
      <Style name="StandardText" template="StandardExtendedTemplate" height="16" textcolor="#ColorWhite"/>
      <Style name="HeaderText" template="HeaderExtendedTemplate" height="24" textcolor="#ColorWhite"/> 
    
      <Style name="StandardParagraphText" template="StandardText" hjustify="Left" vjustify="Top"/>
      <Style name="HeaderCenterText" template="HeaderText" hjustify="Center" vjustify="Middle"/>
    
      <Style name="DialogItemText" template="HeaderText" height="20" hjustify="Left" vjustify="Middle"/>
      <Style name="DialogButtonText" template="HeaderText" hjustify="Center" vjustify="Middle"/>
    </StyleFile>
    

    All we did was add the styles "DialogItemText", which will be used in dialog items like edit and list boxes, and "Dialog Button Text" which will be used for our OK and Cancel buttons. You'll note that DialogButtonText is the same as HeaderCenterText.

    Import this new style file into your map.

    Style Constants

    Strings can be constants too. In fact, most variable types except records and arrays can be constants. We're going to start using string constants for our style names. Why? Because it significantly reduces the chance for typos. That's really the only reason, but it's a good one so I suggest you do it. Inside the Dialog Constants folder, create a new folder called "Styles". In it, add the following four constants:

                cStandard Text = "StandardParagraphText" <String (Constant)>
                cHeader Text = "HeaderCenterText" <String (Constant)>
                cDialog Item Text = "DialogItemText" <String (Constant)>
                cDialog Button Text = "DialogButtonText" <String (Constant)>
    

    Create Dialog

    We're going to start out with a simple edit box dialog:

    Edit Box Dialog

    Something like this might look familar to anyone who's every used a GUI before. We're just looking to get a single string input from the user, with the option to accept or cancel. Simple, but very reusable. We can just show this dialog anytime we need to get such input from the user. We're even going to make it so we can customize the header and the default string each time we show it. Feel free to use this directly in any map you make.

    So we'll start by creating a folder for our dialog. Call it "Edit Box Dialog". This time, we'll use a record to store all our dialog data in a single place. So inside the folder, create a new record and call it "Edit Box Dialog Data":

    Edit Box Dialog Data

    Our record has 5 variables, a single dialog and 4 dialog items. We'll need to keep track of the OK and Cancel buttons so that we know when they've been used. We'll also need to track the header and edit box items so that we can set their values. Also, we'll need the edit box item so that we can get it's value after we're done.

    So now we actually have to create a variable for our record, so let's do that. I called mine "Global Edit Box Dialog". The "Global" part might seem a little redundant, but I use Global to signify that there is one dialog for all players.

    We're going to need one more variable, and this one is per player. We'll need to keep track of whether the user hit OK or cancel. We can do this with a simple boolean. So create a variable called "Player Edit Box Dialog Status" of type boolean, and make it an array with 16 elements.

    Your Edit Box Dialog folder should now look like this:

    Edit Box Dialog Folder

    Dialog Calculations

    Create a new action definition called "Edit Box Dialog - Create". Once again, we're going to start off with several calculations:

    Dialog Height

            Dialog Height = (+ (cDialog Extra, cHeader Height, cRow Gap, cEdit Box Height,
                  cDialog Button Gap, cDialog Button Height)) <Integer>
    

    If you're having trouble trying to figure out how to calculate your sizes, it sometimes helps to draw them out:

    Height Breakdown

    1. cDialog Border
    2. cHeader Height
    3. cRowGap
    4. cEdit Box Height
    5. cDialog Button Gap
    6. cDialog Button Height

    Of course, you don't normally have a completed dialog to look at, but you can get about the same results on graph paper or in a Photoshop-like program. Microsoft Excel is also pretty good for drawing things out in a grid. That's what I typically use.

    Our dialog height is just the sum of a bunch of numbers: cDialog Extra (which is cDialog Border * 2), cHeader Height + cRow Gap, cEdit Box Height, and cDialog Button Gap + cDialog Button Height.


    Dialog Width

            Dialog Width = (+ (cEdit Box Width, cDialog Extra)) <Integer>
    

    The width is a real simple calculation. We're just going to add a dialog border to the width of our edit box. The dialog won't be any wider than that.


    Edit Offset Y

            Edit Offset Y = (+ (cDialog Border, cHeader Height, cRow Gap)) <Integer>
    

    Another fairly simple calculation. We could just keep a running Y variable like we did in part 1, or we could calculate our offsets ahead of time. Either way works fine, and it can depend on the sitation. Hopefully, this calculation makes sense. Since the header will be placed at cDialog Border, we want the edit box to be offset by the height of the header plus the gap.


    Button Offset Y

            Button Offset Y = (+ (Edit Offset Y, cEdit Box Height, cDialog Button Gap)) <Integer>
    

    This calculation builds on top of the last. We know where the edit box will go, so if we add cEdit Box Height and cDialog Button Gap to it, we can determine where the buttons will be placed.


    Button Offset X

    This one's a little trickier, and will be calculated in three parts:

            Inner Width = (Dialog Width - cDialog Extra) <Integer>
    

    The dialog inner width is something I calculate all the time. It's useful in this situation because of the way we want to center the dialog buttons, which I'll demonstrate in a second. You may notice that Inner Width will come out to equal cEdit Box Width, but this is not always the case. Also, since we may at some time change the dialog width, it's best to just keep the calculation the way it is. The inner width will always equal the dialog width minus cDialog Extra, no matter what.

            Half Inner Width = (Inner Width / 2) <Integer>
    

    An easy calculation, but it might not be immediately obvious why we need it. Let's first take a look at how we want our dialog to look:

    Width Breakdown

    1. Inner Width
    2. Half Inner Width
    3. Button Offset X

    We want to center our buttons across half of the dialog, so we need to calculate this span which we will use as the "total width" in a call to the Center function we created:

            Button Offset X = (+ ((Center(Half Inner Width, cDialog Button Width)),
                     cDialog Border)) <Integer>
    

    Button Offset X

    Now that we have Half Inner Width, we want to center cDialog Button Width across it. Finally, we need to add back in cDialog Border, because we removed it when we calculated the Inner Width.

    We calculated this is three parts for several reasons. For one, it's just easier to break up a calculation into several pieces and then each individual calcuation becomes more manageable. Also, we're going to need Half Inner Width again. You'll notice we only calculated the offset of the OK button. Cleverly, however, we can just add Half Inner Width to that and we'll have the offset of our Cancel button. Inner Width will also end up being the width of our header.

    Drawing the Dialog

    As our dialog drawing functions get longer, it's useful to add comments to break up individual sections and label them.

            ------- Dialog
            Dialog - Create a Modal dialog of size (Dialog Width, Dialog Height)
                   at (0, 0) relative to Center of screen
            Variable - Set Global Edit Box Dialog.Dialog = (Last created dialog)
    

    This should be review. We've already calculated the width and height, and we want to place it in the dead center of the screen.

            ------- Header
            Dialog - Create a label for dialog (Last created dialog) with the dimensions 
                  (Inner Width, cHeader Height) anchored to Top Left with an offset of 
                  (cDialog Border, cDialog Border) with the text "Header"
                  color set to White text writeout set to false with a writeout duration of 2.0
            Variable - Set Global Edit Box Dialog.Header = (Last created dialog item)
            Dialog - Set (Last created dialog item) style to cHeader Text for (All players)
    

    Once again, we've been there and we've done this before. The only difference is that we're now using a string constant for the dialog item style.

            ------- Edit Box
            Dialog - Create a Edit Box for dialog (Last created dialog)
            Variable - Set Global Edit Box Dialog.Edit Box = (Last created dialog item)
            Dialog - Set (Last created dialog item) style to cDialog Item Text
                   for (All players)
            Dialog - Move (Last created dialog item) to (cDialog Border, Edit Offset Y)
                   relative to Top Left of dialog for (All players)
            Dialog - Set (Last created dialog item) size to (cEdit Box Width, cEdit Box Height)
                   for (All players)
    

    Now this part is a little bit different from what we've done before. Unlike labels, buttons, and images, there isn't a specific function for creating edit boxes. Instead, we will use the function "Create Dialog Item" and set the type to "Edit Box". Create Dialog Item doesn't have parameters for size and offset, so we'll have to move and resize the dialog item with seperate calls. We will still save our dialog item into a variable and set the dialog item style the same way as before.

            ------- OK Button
            Dialog - Create a button for dialog (Last created dialog) with the dimensions 
                   (cDialog Button Width, cDialog Button Height) anchored to Top Left 
                   with an offset of (Button Offset X, Button Offset Y) setting the tooltip to ""
                   with button text "OK" and the hover image set to ""
            Variable - Set Global Edit Box Dialog.OK Button = (Last created dialog item)
            Dialog - Set (Last created dialog item) style to cDialog Button Text for (All players)
            ------- Cancel Button
            Variable - Modify Button Offset X: + Half Inner Width
            Dialog - Create a button for dialog (Last created dialog) with the dimensions
                   (cDialog Button Width, cDialog Button Height) anchored to Top Left
                   with an offset of (Button Offset X, Button Offset Y) setting the tooltip to ""
                   with button text "Cancel" and the hover image set to ""
            Variable - Set Global Edit Box Dialog.Cancel Button = (Last created dialog item)
            Dialog - Set (Last created dialog item) style to cDialog Button Text for (All players)
    

    More basic button creation. Since we calculated everything ahead of time, this is all pretty easy. Notice that we add Half Inner Width to Button Offset X before creating the cancel button.

    Dialog Initialization

    In the main dialog folder, create an action definition called "Dialog Initialization". In it, call the Edit Box Dialog - Create function we just made. Open up the Melee Initialization trigger, and call Dialog Initialization from there. It's probably a good idea to move the two other calls in our Melee Initialization into our Dialog Initialization action, so that it will look like this:

    Dialog Initialization

    Test Our Dialog

    Always a good idea to test often, so let's actually add a Show Dialog line to the end of our Edit Box Dialog - Create function and test our document. Don't forget to delete this line after you are done. You should get something that look something like this:

    Test Dialog

    Some Tweaks

    I think you'll agree that the header looks a little off. This is partly because the font is too small, and partly because the gap is too small. We're using cRow Gap for our gap and we really shouldn't be. So I'm going to create a new constant called cHeader Gap and set it to 10. Inside Edit Box Dialog - Create, I changed every instance of cRow Gap (there are two) with cHeader Gap. Then, I changed the height of HeaderCenterText to 28 inside our style file and reimported it. It did not change the height of DialogButtonText. Since we changed our style height, we also need to change cHeader Height, which I changed to 32.

    Just a few tweaks and I think our dialog looks quite a bit better:

    After a Couple Tweaks

    Show/Hide Dialog

    As I said before, we're going to be creating an action definition for showing our dialog, and another one for hiding it. This isn't entirely true. Our show dialog action is actually going to be a function. This is, we want it to return something. What is it goint to return? Our function is actually going to wait until the user is done with the dialog, and return the string that they typed. If they hit cancel, it will return an empty string (""). This is what's the most useful, I think, for use in a general program, where you don't want to set up a trigger every time. You really just want to know what they typed in.

    Show Dialog

    So create a new function in our Edit Box Dialog folder, and call it "Edit Box Dialog - Show". The return type will be string. It will take three parameters. The first is the player number and is very important. The second will be the header text. This will be of type text so that styles and colors can be used if desired. The third parameter will be the default string to put in the edit box. This has to be of type string, because the edit box won't accept text. You should have something like this:

    Edit Box Dialog - Show
        Options: Function
        Return Type: String
        Parameters
            Player = 0 <Integer>
            Header = No Text <Text>
            Default String = "" <String>
    

    The first couple of lines are pretty straightforward:

            Dialog - Set Global Edit Box Dialog.Header text to Header for (Player group(Player))
            Dialog - Set Global Edit Box Dialog.Edit Box edit value to Default String 
                   for (Player group(Player))
            Dialog - Show Global Edit Box Dialog.Dialog for (Player group(Player))
    

    What's really important to note is that we're using (Player group(Player)), which is "Convert Player to Player Group" > Parameter > Player. We are not using "All Players", which is the default. We only want to do these steps for one player. First, we set the header text to our header parameter. Then we set the edit box value to our default string parameter. Finally, we show the dialog. Then, we wait...

            General - Wait for (Conditions), checking every cDialog Wait Time Game Time seconds
                Conditions
                    (Global Edit Box Dialog.Dialog is visible for Player) == false
            General - If (Conditions) then do (Actions) else do (Actions)
                If
                    Player Edit Box Dialog Status[Player] == true
                Then
                    General - Return (Edit value of Global Edit Box Dialog.Edit Box for Player)
                Else
                    General - Return ""
    

    Oops! There's a dialog constant in there I haven't brought up yet, but we'll come back to that...

    We start a wait loop, checking every "cDialog Wait Time" (0.25) seconds, to see if the dialog is still visible for the player. There's a number of ways you can check to see if a user is done with a dialog, but checking for visibility is my personal favorite. It doesn't require we track another variable or anything like that, and it's fairly simple to check.

    For the next step, we check the Player Edit Box Status for this player. We'll set this variable in our trigger. If true, the user didn't hit cancel, and we want to return the edit value of our edit box dialog item. If false, the user hit cancel and the contents of the edit box are irrelevant, so we return an empty string ("").

    Now, about that constant. Generally I feel that 0.25 seconds is a sufficient wait time for dialog responses, but you might disagree. Dialogs rely on user input and typically don't have to be super responsive. You do want them to be responsive enough, however, that the user doesn't really notice any lag. I think 0.25 seconds hits that sweet spot without taking up a huge amount of processor time. Different implementations might call for different times. This uncertainty alone is enough reason to create a constant. We'll add it to our dialog constants folder, and it will be of type real. Try using 0.25 for the value. If you don't like it, you can always change it.

    Hide Dialog

    It doesn't get much easier than this:

    Edit Box Dialog - Hide
        Options: Action
        Return Type: (None)
        Parameters
            Player = 0 <Integer>
        Local Variables
        Actions
            Dialog - Hide Global Edit Box Dialog.Dialog for (Player group(Player))
    

    As I said before, it's just one line but we're making it a seperate action definition anyways. Also, make sure you're changing "All Players" to be "(Player group(Player))".

    Dialog Callback

    There's just one more step before we can actually use our dialog, so let's just jump right in:

    Edit Box Dialog - Callback
        Events
            Dialog - Any Dialog Item is used by Player Any Player with event type Clicked
        Local Variables
            Edit Value = (Edit value of Global Edit Box Dialog.Edit Box for 
                       (Triggering player)) <String>
        Conditions
            Or
                Conditions
                    (Used dialog item) == Global Edit Box Dialog.OK Button
                    (Used dialog item) == Global Edit Box Dialog.Cancel Button
        Actions
            General - If (Conditions) then do (Actions) else do (Actions)
                If
                    And
                        Conditions
                            (Used dialog item) == Global Edit Box Dialog.OK Button
                            Edit Value == ""
                Then
                    General - Skip remaining actions
                Else
            Edit Box Dialog - Hide((Triggering player))
            General - If (Conditions) then do (Actions) else do (Actions)
                If
                    (Used dialog item) == Global Edit Box Dialog.Cancel Button
                Then
                    Variable - Set Player Edit Box Dialog Status[(Triggering player)] = false
                Else
                    Variable - Set Player Edit Box Dialog Status[(Triggering player)] = true
    

    It looks a lot more complicated than it is. Since there are exactly two buttons they could have pushed for this dialog, we can check for those in the conditions using an "Or" condition. Then, we use an if statement to check if the user hit the OK button but the edit box is blank. If they do, we just ignore the fact that they hit the OK button using the action "Skip remaining actions". They need to either put something in the edit box or hit cancel. Once we know that they did one of those two things, we can hide the dialog. Finally, we set Player Edit Box Dialog Status to true or false, depending on whether the cancel button was hit or not.

    Using Our Dialog

    You already removed the line that shows the dialog at the end of Edit Box Dialog - Create, right? Good.

    Let's go back into our Unit Selection Dialog folder, and open up the callback for that dialog. In it, we create a unit based on what the user selected. What if we wanted them to be able to name that unit? Simple.

    First, create a new variable called "Unit Name" of type string. Then, immediately after the unit is created, add the following line:

           Variable - Set Unit Name = (Edit Box Dialog - Show((Triggering player), "Unit Name", ""))
    

    We want to set Unit Name equal to the return value of our function. Triggering player will be our player parameter, and "Unit Name" will be our header. Unfortunately, we can't get the unit name or the player's name as a string to use as the default string, so we'll have to just leave it blank. You could set it to "Test" or something if you wanted to see it working.

    Now, we want to actually do something with this string, so we'll just keep it easy and add a text tag to the unit we created:

           Text Tag - Create a text tag with the text (Text(Unit Name)) for (All players), 
                   using a font size of 24, at (Position of (Last created unit)) 
                   and height offset 1.0, initially Visible, and fog of war enforcement
                   set to false
           Text Tag - Attach (Last created text tag) to (Last created unit) with
                   height offset 1.0
    

    Give your map a test, and you should be able to name your unit:

    My Archon

    Taking it to the Next Level

    In this situation, we probably would not want to allow the user to cancel our dialog. In other cases, we might still want to allow it. What we really need is the flexibility to do either from the same dialog. We can definitely do that.

    What we could do is move the OK button and hide/show the cancel button as needed. To do this, we'd need to keep track of where we need to move the OK button to. We would need Button Offset X as well as a centered button offset to be global variables instead of local. This would definitely work, but there's a slightly easier way.

    We could just create 3 buttons. We have two OK buttons, one centered and one to the left, and we only show one at a time. We would still show/hide the cancel button as needed.

    We'll start by modifying our Edit Box Dialog Data record. We'll need to add a new dialog item variable to it, called "Centered OK Button". Rename "OK Button" to "Left OK Button" to avoid confusion.

    Edit Box Dialog Data record

    Open up Edit Box Dialog - Create and add a new variable:

            Centered Button Offset X = (Center(Dialog Width, cDialog Button Width)) <Integer>
    

    Then, add the following lines to the very bottom:

            ------- Centered OK Button
            Dialog - Create a button for dialog (Last created dialog) with the dimensions 
                   (cDialog Button Width, cDialog Button Height) anchored to Top Left
                   with an offset of (Centered Button Offset X, Button Offset Y)
                   setting the tooltip to "" with button text "OK" and the hover image set to ""
            Variable - Set Global Edit Box Dialog.Centered OK Button = (Last created dialog item)
            Dialog - Set (Last created dialog item) style to cDialog Button Text for (All players)
    

    Then, let's jump into our Edit Box Dialog - Show function. It will need a new parameter, type boolean, called "Allow Cancel". Set the default value to true. Then, add the following code to the very beginning of the function:

            General - If (Conditions) then do (Actions) else do (Actions)
                If
                    Allow Cancel == true
                Then
                    Dialog - Show Global Edit Box Dialog.Left OK Button for (Player group(Player))
                    Dialog - Show Global Edit Box Dialog.Cancel Button for (Player group(Player))
                    Dialog - Hide Global Edit Box Dialog.Centered OK Button for (Player group(Player))
                Else
                    Dialog - Hide Global Edit Box Dialog.Left OK Button for (Player group(Player))
                    Dialog - Hide Global Edit Box Dialog.Cancel Button for (Player group(Player))
                    Dialog - Show Global Edit Box Dialog.Centered OK Button for (Player group(Player))
    

    Hopefully this is self-explanatory. If Allow Cancel is true, show the normal two buttons, otherwise hide them and show only the centered button.

    Lastly, we just need to make a few small changes to our callback function trigger. Add Centered OK Button to the condition such that it looks like this:

        Conditions
            Or
                Conditions
                    (Used dialog item) == Global Edit Box Dialog.Left OK Button
                    (Used dialog item) == Global Edit Box Dialog.Centered OK Button
                    (Used dialog item) == Global Edit Box Dialog.Cancel Button
    

    Then, change the first condition to this:

            General - If (Conditions) then do (Actions) else do (Actions)
                If
                    And
                        Conditions
                            (Used dialog item) != Global Edit Box Dialog.Cancel Button
                            Edit Value == ""
    

    We could have checked for both OK buttons, but it's easier to just check and see that it's not the cancel button. So what we did was change OK Button to Cancel Button and == was changed to !=.

    Go back into the Unit Selection Dialog - Callback trigger, and set Allow Cancel to false. Give it a test, and you should see:

    Centered OK Button

    Because of the changes we made to the callback, you still will not be able to hit OK if the edit box is blank. Note that if you set Allow Cancel to false, you will get the normal edit box dialog.

    Conclusion

    Most of the other dialog items behave in the same way as the edit box. Remember that you will need to set the size and position of a dialog item created with "Create Dialog Item". With the edit box, we made extensive use of the "Dialog Item Edit Value", which is specific to the edit box. For other dialog items, there may be another specific function used to get it's value, and finding this may take a little trial-and-error. If you have any trouble, please feel free to post questions here, or join the sc2mapster IRC channel and ask questions there.

    We also covered showing different things to different players. I spoke briefly about how you can't resize or move a dialog for only one player. To do that, you would need another method which is not covered here. The method we used, however, works in every other case which is a vast majority of dialogs. You can move, hide, show, or resize dialog items for only one player. You can also change their contents like we say with our header and with the edit box value. GE gives a great deal of flexibility to maintain a single dialog, while showing different things to different players at different times. Although it may seem confusing at first, in the long run it is a lot easier to manage.

    Posted in: Tutorials
  • 0

    posted a message on [Dialogs] Really Great Looking Dialogs, Part 2

    Updated downloadable map to reflect the changes made to part 1 (http://forums.sc2mapster.com/resources/tutorials/17969-dialogs-really-great-looking-dialogs-part-1/?page=2#p25). This also required a slight change to tutorial with regards to how the dialog height is calculated.

    Posted in: Tutorials
  • 0

    posted a message on [Dialogs] Really Great Looking Dialogs, Part 1

    I've updated the tutorial.

    • I've refactored the way that the Unit Buttons record array is initialized. The way used now is a great deal more robust and doesn't require as much copy/pasting. It is a better way to initalize records overall, so I wanted to start people out on the right foot.
    • This refactoring also led to a slight change in how nRows was calculated (the +1 part was removed). Several people have asked about this calculation, specifically the use of the "Ceiling" function, so I've added some clarification.
    • I added an if statement to the dialog creation loop so it doesn't try to draw extra buttons in the event that nUnit Buttons is not directly divisible by nCols.
    • Finally, I was adding an extra button gap to both the width and height of the dialog. The old calculation was:
            Dialog Width = (+ (cDialog Extra, ((+ (cButton Size, cButton Gap)) * nCols))) <Integer>
            Dialog Height = (+ (cDialog Extra, ((+ (cButton Size, cButton Gap)) * nRows))) <Integer>
    

    When it should be:

            Dialog Width = (+ (cDialog Extra, (cButton Size * nCols), (cButton Gap * (nCols - 1)))) <Integer>
            Dialog Height = (+ (cDialog Extra, (cButton Gap * nRows), (cButton Gap * (nRows - 1)))) <Integer>
    

    This results in a little extra complexity that needs to be explained, but I think it's important to do it right regardless. Currently, the extra gap is barely noticeable (if you look real close you can see it), but becomes much more dramatic if a larger gap is used. Although I have changed all or the code and explanations, I have not changed any of the images of the actual dialogs, and I'm not sure I ever will. The difference just isn't large enough.


    If you've already gone through this tutorial, you may wish to look these changes over to see how/if they affect you. I do recommend making these changes, as they will result in better code being written by you in the long run.


    An updated map has been uploaded as well.

    Posted in: Tutorials
  • 0

    posted a message on NA Map Nights

    I'm sorry, but something very important came up, and I will be unable to make map night tonight. If someone else wants to host in my place, that would be great.

    Posted in: General Chat
  • To post a comment, please or register a new account.