Difference between revisions of "MessageBox Tutorial/Ensuring Your Menu Is Seen"

From the Oblivion ConstructionSet Wiki
Jump to navigation Jump to search
imported>Haama
(Better Basics)
imported>Haama
(Removed from category)
 
(3 intermediate revisions by 2 users not shown)
Line 7: Line 7:
----
----


If another menu is shown before the player makes a decision, that other menu will overwrite your menu (the player will see the other menu), and any decision the player makes will be limited to that other menu. This leads to a few problems:
If another menu is shown before the player makes a decision, that other menu will overwrite your menu. That is, your menu will be erased and the new menu will be shown instead. This leads to a few problems:
*The player can no longer respond to your menu
*Your script will continue to run, once a frame, at least these lines:
*Your script will continue to run, once a frame, at least these lines:
<pre>  if (Choosing == 0)
<pre>  if (Choosing == 0)
...
...
   Elseif (Choosing > 0) && (Choice == -1) ;No choice yet
   Elseif (Choosing > 0) && (Choice == -1) ;No choice yet
     Set Choice to GetButtonPressed
     Set Choice to GetButtonPressed</pre>
    Return</pre>
until the menu is started up again (activated again).  
until the menu is started up again (activated again).  
*Your script won't run through the exit <u>'''''if (Choosing == 0)'''''</u>
*Your script won't run through the exit <u>'''''if (Choosing == 0)'''''</u>
*Again, the player won't see or be able to answer your menus


To make sure your menu is read a timer will start counting down when the (yours or another mod's) menu closes. If the player responded to your menu, the '''''Choice''''' will be updated (> -1). If the player responded to another menu, '''''Choice''''' won't be updated and the timer will run down. Once the timer reaches 0, your menu will be displayed again. This also gives the other mod's menus a chance to finish up, as any new menu will restart the timer.
 
To avoid this, add a timer (well, counter, but same principle). If [[GetButtonPressed]] returns the player's decision (> -1), then your menu was responded to. If it remains -1 after the timer runs out, then another menu must have overwritten yours, and you can make yours pop up again. The timer will be long enough to allow the other menu script to finish before showing your previous menu again.


To do all this, replace:
To do all this, replace:
<pre>  Elseif (Choosing > 0) && (Choice == -1) ;No choice yet
<pre>  Elseif (Choosing > 0) && (Choice == -1) ;No choice yet
     Set Choice to GetButtonPressed
     Set Choice to GetButtonPressed
    Return</pre>
</pre>
with (due to wiki limitations, the large '''''if''''' test has been given line breaks, whereas in the CS it would all be on one line)
with (due to wiki limitations, the large '''''if''''' test has been given line breaks, whereas in the CS it would all be on one line)
<pre>float MessageTimer
<pre>short MessageCounter
short MessageButton
...
...
   Elseif (Choosing > 0) && (Choice == -1) ;No choice yet
   Elseif (Choosing > 0) && (Choice == -1) ;No choice yet
     if (MessageTimer > 0) || (MessageCounter > 0)
     if (MessageCounter < 30)
       set Choice to GetButtonPressed
       set Choice to GetButtonPressed
       if (Choice > -1)
       if (Choice == -1)
         return
         if (MenuMode 1001 == 0)
      endif
          if (MenuMode 1004 == 0) && (MenuMode 1005 == 0) && (MenuMode 1006 == 0) &&
      if (MenuMode 1001 == 0)
            (MenuMode 1010 == 0) && (MenuMode 1011 == 0) && (MenuMode 1013 == 0) &&
        if (MenuMode 1004) || (MenuMode 1005) || (MenuMode 1006) ||
            (MenuMode 1015 == 0) && (MenuMode 1016 == 0) && (MenuMode 1017 == 0) &&
          (MenuMode 1010) || (MenuMode 1011) || (MenuMode 1013) ||
            (MenuMode 1018 == 0) && (MenuMode 1019 == 0) && (MenuMode 1020 == 0) &&
          (MenuMode 1015) || (MenuMode 1016) || (MenuMode 1017) ||
            (MenuMode 1021 == 0) && (MenuMode 1024 == 0) && (MenuMode 1038 == 0) &&
          (MenuMode 1018) || (MenuMode 1019) || (MenuMode 1020) ||
            (MenuMode 1039 == 0) && (MenuMode 1044 == 0) && (MenuMode 1045 == 0) &&
          (MenuMode 1021) || (MenuMode 1024) || (MenuMode 1038) ||
            (MenuMode 1046 == 0) && (MenuMode 1047 == 0) && (MenuMode 1057 == 0)
          (MenuMode 1039) || (MenuMode 1044) || (MenuMode 1045) ||
            ;These are options menus, etc. where GetButtonPressed won't return anything
          (MenuMode 1046) || (MenuMode 1047) || (MenuMode 1057)
            set MessageCounter to (MessageCounter + 1)
          return
          endif
        else
        else ;MenuMode 1001
          set MessageTimer to (MessageTimer - GetSecondsPassed)
           set MessageCounter to 0
           set MessageCounter to (MessageCounter - 1)
          return
         endif
         endif
       else ;MenuMode 1001
       else ;Choice > -1
        set MessageTimer to 1
         set MessageCounter to 0
         set MessageCounter to 45
        return
       endif
       endif
     else ;Display menu again
     else ;Display menu again
      set Choosing to -(Choosing)
      set MessageCounter to 0
       message "Trying menu again..."
       message "Trying menu again..."
      set Choosing to -(Choosing)
      return
     endif</pre>
     endif</pre>
and whenever you display a menu, setup the MessageTimer to 1 and the MessageCounter to 45, as such:
and when you exit the script, reset the MessageCounter to 0, as such:
<pre> Elseif (Choosing == -1) ;Display your menu
<pre>begin GameMode
    Messagebox "Would you like to donate gold or food?" "Gold" "Food"
  if Working
                                                        "Blood" "Cancel"
     Set Working to 1
    Set Choosing to 1
     Set Choice to GetButtonPressed
    Set MessageTimer to 1
    Set MessageCounter to 45
    Return</pre>
 
And now I'm sure you want to know the details of what all that actually does. When another menu overwrites yours, any response the player makes will be caught by the other script's [[GetButtonPressed]], but not by your script's [[GetButtonPressed]]. That means '''''Choice''''' will always be '''''-1'''''. So, these extra lines will start a countdown once the player has left the menu screen ([[MenuMode]] 1001). If both 1 second and 45 frames pass and [[GetButtonPressed]] is still returning '''''-1''''' then your menu is reset (with <u>'''''set Choosing to -(Choosing)'''''</u>. The countdown won't run when the player presses <ESC> and looks through their options (that's what that whole mess of <u>'''''if (MenuMode 1004)'''''</u>... is for). This won't disturb other menus, because the countdown is reset whenever a new menu is displayed. So, once the other mod's menus are out of the way, your menu will be shown again.


    if (Choosing == 0)
      Set Working to 0
      Set MessageCounter to 0</pre>


[[Category: Scripting Tutorials]]
And now I'm sure you want to know the details of what all that actually does. When another menu overwrites yours, any response the player makes will be caught by the other script's [[GetButtonPressed]], but not by your script's [[GetButtonPressed]]. That means '''''Choice''''' will always be '''''-1'''''. So, these extra lines will start a countdown once the player has left the menu screen ([[MenuMode]] 1001). If 30 frames pass and [[GetButtonPressed]] is still returning '''''-1''''' then your menu is reset (with <u>'''''set Choosing to -(Choosing)'''''</u>. The countdown won't run when the player presses <ESC> and looks through their options (that's what that whole mess of <u>'''''if (MenuMode 1004 == 0)'''''</u>... is for). This won't disturb other menus, because the countdown is reset whenever a new menu is displayed. So, once the other mod's menus are out of the way, your menu will be shown again.

Latest revision as of 18:06, 3 June 2008

This is a subsection of the MessageBox Tutorial, and uses this script as a base. The following code may or may not require certain aspects of that script to work, however the information should prove useful for any script (it will take a bit of care to make it work, though).


For this tutorial, you will want to centralize your decision catching.


If another menu is shown before the player makes a decision, that other menu will overwrite your menu. That is, your menu will be erased and the new menu will be shown instead. This leads to a few problems:

  • The player can no longer respond to your menu
  • Your script will continue to run, once a frame, at least these lines:
  if (Choosing == 0)
...
  Elseif (Choosing > 0) && (Choice == -1) ;No choice yet
    Set Choice to GetButtonPressed

until the menu is started up again (activated again).

  • Your script won't run through the exit if (Choosing == 0)


To avoid this, add a timer (well, counter, but same principle). If GetButtonPressed returns the player's decision (> -1), then your menu was responded to. If it remains -1 after the timer runs out, then another menu must have overwritten yours, and you can make yours pop up again. The timer will be long enough to allow the other menu script to finish before showing your previous menu again.

To do all this, replace:

  Elseif (Choosing > 0) && (Choice == -1) ;No choice yet
    Set Choice to GetButtonPressed

with (due to wiki limitations, the large if test has been given line breaks, whereas in the CS it would all be on one line)

short MessageCounter
...
  Elseif (Choosing > 0) && (Choice == -1) ;No choice yet
    if (MessageCounter < 30)
      set Choice to GetButtonPressed
      if (Choice == -1)
        if (MenuMode 1001 == 0)
          if (MenuMode 1004 == 0) && (MenuMode 1005 == 0) && (MenuMode 1006 == 0) &&
             (MenuMode 1010 == 0) && (MenuMode 1011 == 0) && (MenuMode 1013 == 0) &&
             (MenuMode 1015 == 0) && (MenuMode 1016 == 0) && (MenuMode 1017 == 0) &&
             (MenuMode 1018 == 0) && (MenuMode 1019 == 0) && (MenuMode 1020 == 0) &&
             (MenuMode 1021 == 0) && (MenuMode 1024 == 0) && (MenuMode 1038 == 0) &&
             (MenuMode 1039 == 0) && (MenuMode 1044 == 0) && (MenuMode 1045 == 0) &&
             (MenuMode 1046 == 0) && (MenuMode 1047 == 0) && (MenuMode 1057 == 0)
             ;These are options menus, etc. where GetButtonPressed won't return anything
            set MessageCounter to (MessageCounter + 1)
          endif
        else ;MenuMode 1001
          set MessageCounter to 0
        endif
      else ;Choice > -1
        set MessageCounter to 0
      endif
    else ;Display menu again
      set Choosing to -(Choosing)
      set MessageCounter to 0
      message "Trying menu again..."
    endif

and when you exit the script, reset the MessageCounter to 0, as such:

begin GameMode
  if Working
    Set Working to 1

    if (Choosing == 0)
      Set Working to 0
      Set MessageCounter to 0

And now I'm sure you want to know the details of what all that actually does. When another menu overwrites yours, any response the player makes will be caught by the other script's GetButtonPressed, but not by your script's GetButtonPressed. That means Choice will always be -1. So, these extra lines will start a countdown once the player has left the menu screen (MenuMode 1001). If 30 frames pass and GetButtonPressed is still returning -1 then your menu is reset (with set Choosing to -(Choosing). The countdown won't run when the player presses <ESC> and looks through their options (that's what that whole mess of if (MenuMode 1004 == 0)... is for). This won't disturb other menus, because the countdown is reset whenever a new menu is displayed. So, once the other mod's menus are out of the way, your menu will be shown again.