Text Input With OBSE

Revision as of 15:23, 1 February 2008 by imported>DragoonWraith (→‎Final Comments: doesn't QUITE work as-is, need to specify a place to store the string)

This code will accept keystrokes from the player, and display the text they write in a MessageBox. It will properly account for the Shift key and the Backspace key, and it will do so without causing any bloating whatsoever.

Setup

First of all, this script requires the Oblivion Script Extender, v0014 or higher.

The script stores the string in the name of an object - you need an object defined for this purpose. This object may be anything that has a name, though it is highly recommended that the player never see it, or if they do, make sure it is after they have named it. An activator is most likely the best choice.

The string must have an initial value that includes an accent mark (`). I used "`Enter Name`". To use any other name, the script must be changed in four places - and these four places must have the same value.

Further, you also need a separate Activator to actually put the script on. This Activator also must be placed in the gameworld somewhere, and the reference must be marked Persistent and given a reference ID.

Limitations

The script as-is only supports Roman letters, spaces, dashes, and apostrophes. Support for additional characters is relatively simple, but keep in mind that you will have to do this yourself if you desire it.

Further, Caps Lock is ignored. Given that it is generally used for running, this is probably preferable, but supporting Caps Lock could be added to the script with little effort.

Finally, it is impossible to support the accent mark (`), tilde (~), or double-quotation mark ("). The first two cannot be supported because it is impossible for the player to actually type these without opening the Console - even using DisableKey on the character will not allow them to avoid opening the console with the key. The last cannot be supported simply because it is impossible to include one within a string in a script, as it ends the string (and Oblivion does not include any escape character for it).

Relevant Functions

The following functions are used in this code:

It is recommended that you have some idea of what these functions do and how they work.

The Code

scn TextInputBox
; Object script, goes on an Activator

short state
short caps
short button

ref StringVar

Begin GameMode

  if ( state )
    Activate player 1
  endif

End

Begin MenuMode

  if ( state )
    Activate player 1
  endif

End

Begin OnActivate

  if ( state == 0 )
    OnKeyDown 57  ; clears the counter from the initial press when activating the item
    GetButtonPressed  ; clears the counter as well
    if ( StringVar == 0 )
      set StringVar to INSERT_OBJECT_ID_HERE  ; this is where your string gets stored
    endif
    SetName "`Enter Name`~" StringVar  ; !!! Initial Name !!!
    set state to 1

  elseif ( state == 1 )
    ModName "~|" StringVar
    MessageBoxEx "%n|Done" StringVar  ; the specific text can be changed to meet your needs
    ModName "`Enter Name`|" StringVar  ; !!! Initial Name !!!
    AppendToName "~" StringVar
    set state to 2

  elseif ( state == 2 )
    ; first, standard MessageBox menu stuffs
    set button to GetButtonPressed + 1
    PrintC "button %0.f" state
    if ( button )  ; pressed Done
      set state to 3
      return
    endif

    ; now String-capturing code
    set caps to 0
    if ( IsKeyPressed3 42 ) || ( IsKeyPressed3 54 )  ; either Shift key
      set caps to 1
    endif

    if ( OnKeyDown 16 )
      if ( caps )
        ModName "~|Q~" StringVar
      else
        ModName "~|q~" StringVar
      endif
      set state to 1
    elseif ( OnKeyDown 17 )
      if ( caps )
        ModName "~|W~" StringVar
      else
        ModName "~|w~" StringVar
      endif
      set state to 1
    elseif ( OnKeyDown 18 )
      if ( caps )
        ModName "~|E~" StringVar
      else
        ModName "~|e~" StringVar
      endif
      set state to 1
    elseif ( OnKeyDown 19 )
      if ( caps )
        ModName "~|R~" StringVar
      else
        ModName "~|r~" StringVar
      endif
      set state to 1
    elseif ( OnKeyDown 20 )
      if ( caps )
        ModName "~|T~" StringVar
      else
        ModName "~|t~" StringVar
      endif
      set state to 1
    elseif ( OnKeyDown 21 )
      if ( caps )
        ModName "~|Y~" StringVar
      else
        ModName "~|y~" StringVar
      endif
      set state to 1
    elseif ( OnKeyDown 22 )
      if ( caps )
        ModName "~|U~" StringVar
      else
        ModName "~|u~" StringVar
      endif
      set state to 1
    elseif ( OnKeyDown 23 )
      if ( caps )
        ModName "~|I~" StringVar
      else
        ModName "~|i~" StringVar
      endif
      set state to 1
    elseif ( OnKeyDown 24 )
      if ( caps )
        ModName "~|O~" StringVar
      else
        ModName "~|o~" StringVar
      endif
      set state to 1
    elseif ( OnKeyDown 25 )
      if ( caps )
        ModName "~|P~" StringVar
      else
        ModName "~|p~" StringVar
      endif
      set state to 1
    elseif ( OnKeyDown 30 )
      if ( caps )
        ModName "~|A~" StringVar
      else
        ModName "~|a~" StringVar
      endif
      set state to 1
    elseif ( OnKeyDown 31 )
      if ( caps )
        ModName "~|S~" StringVar
      else
        ModName "~|s~" StringVar
      endif
      set state to 1
    elseif ( OnKeyDown 32 )
      if ( caps )
        ModName "~|D~" StringVar
      else
        ModName "~|d~" StringVar
      endif
      set state to 1
    elseif ( OnKeyDown 33 )
      if ( caps )
        ModName "~|F~" StringVar
      else
        ModName "~|f~" StringVar
      endif
      set state to 1
    elseif ( OnKeyDown 34 )
      if ( caps )
        ModName "~|G~" StringVar
      else
        ModName "~|g~" StringVar
      endif
      set state to 1
    elseif ( OnKeyDown 35 )
      if ( caps )
        ModName "~|H~" StringVar
      else
        ModName "~|h~" StringVar
      endif
      set state to 1
    elseif ( OnKeyDown 36 )
      if ( caps )
        ModName "~|J~" StringVar
      else
        ModName "~|j~" StringVar
      endif
      set state to 1
    elseif ( OnKeyDown 37 )
      if ( caps )
        ModName "~|K~" StringVar
      else
        ModName "~|k~" StringVar
      endif
      set state to 1
    elseif ( OnKeyDown 38 )
      if ( caps )
        ModName "~|L~" StringVar
      else
        ModName "~|l~" StringVar
      endif
      set state to 1
    elseif ( OnKeyDown 44 )
      if ( caps )
        ModName "~|Z~" StringVar
      else
        ModName "~|z~" StringVar
      endif
      set state to 1
    elseif ( OnKeyDown 45 )
      if ( caps )
        ModName "~|X~" StringVar
      else
        ModName "~|x~" StringVar
      endif
      set state to 1
    elseif ( OnKeyDown 46 )
      if ( caps )
        ModName "~|C~" StringVar
      else
        ModName "~|c~" StringVar
      endif
      set state to 1
    elseif ( OnKeyDown 47 )
      if ( caps )
        ModName "~|V~" StringVar
      else
        ModName "~|v~" StringVar
      endif
      set state to 1
    elseif ( OnKeyDown 48 )
      if ( caps )
        ModName "~|B~" StringVar
      else
        ModName "~|b~" StringVar
      endif
      set state to 1
    elseif ( OnKeyDown 49 )
      if ( caps )
        ModName "~|N~" StringVar
      else
        ModName "~|n~" StringVar
      endif
      set state to 1
    elseif ( OnKeyDown 50 )
      if ( caps )
        ModName "~|M~" StringVar
      else
        ModName "~|m~" StringVar
      endif
      set state to 1
    elseif ( OnKeyDown 12 )
      if ( caps )
        ModName "~|_~" StringVar
      else
        ModName "~|-~" StringVar
      endif
      set state to 1
    elseif ( OnKeyDown 57 )
      ModName "~| ~" StringVar
      set state to 1
    elseif ( OnKeyDown 40 )  ; CANNOT type double-quote mark
      ModName "~|'~" StringVar
      set state to 1

    elseif ( OnKeyDown 14 ) ; Backspace
      ModName "`Enter Name`~|~" StringVar  ; !!! Initial Name !!!
      ModName "q~|~" StringVar
      ModName "w~|~" StringVar
      ModName "e~|~" StringVar
      ModName "r~|~" StringVar
      ModName "t~|~" StringVar
      ModName "y~|~" StringVar
      ModName "u~|~" StringVar
      ModName "i~|~" StringVar
      ModName "o~|~" StringVar
      ModName "p~|~" StringVar
      ModName "a~|~" StringVar
      ModName "s~|~" StringVar
      ModName "d~|~" StringVar
      ModName "f~|~" StringVar
      ModName "g~|~" StringVar
      ModName "h~|~" StringVar
      ModName "j~|~" StringVar
      ModName "k~|~" StringVar
      ModName "l~|~" StringVar
      ModName "z~|~" StringVar
      ModName "x~|~" StringVar
      ModName "c~|~" StringVar
      ModName "v~|~" StringVar
      ModName "b~|~" StringVar
      ModName "n~|~" StringVar
      ModName "m~|~" StringVar
      ModName "-~|~" StringVar
      ModName "_~|~" StringVar
      ModName " ~|~" StringVar
      ModName "'~|~" StringVar

      ; if the string is empty, restore the initial name.
      ; NOTE: due to page width restrictions, these three lines had to be wrapped
      if ( CompareName "q~" StringVar == 0  ) && ( CompareName "w~" StringVar == 0  )
&& ( CompareName "e~" StringVar == 0  ) && ( CompareName "r~" StringVar == 0  )
&& ( CompareName "t~" StringVar == 0  ) && ( CompareName "y~" StringVar == 0  )
&& ( CompareName "u~" StringVar == 0  ) && ( CompareName "i~" StringVar == 0  )
&& ( CompareName "o~" StringVar == 0  ) && ( CompareName "p~" StringVar == 0  )
        if ( CompareName "a~" StringVar == 0  ) && ( CompareName "s~" StringVar == 0  )
&& ( CompareName "d~" StringVar == 0  ) && ( CompareName "f~" StringVar == 0  )
&& ( CompareName "g~" StringVar == 0  ) && ( CompareName "h~" StringVar == 0  )
&& ( CompareName "j~" StringVar == 0  ) && ( CompareName "k~" StringVar == 0  )
&& ( CompareName "l~" StringVar == 0  )
          if ( CompareName "z~" StringVar == 0  ) && ( CompareName "x~" StringVar == 0  )
&& ( CompareName "c~" StringVar == 0  ) && ( CompareName "v~" StringVar == 0  )
&& ( CompareName "b~" StringVar == 0  ) && ( CompareName "n~" StringVar == 0  )
&& ( CompareName "m~" StringVar == 0  ) && ( CompareName "-~" StringVar == 0  )
&& ( CompareName " ~" StringVar == 0  ) && ( CompareName "'~" StringVar == 0  )
            ModName "~|`Enter Name`~" StringVar  ; !!! Initial Name !!!
          endif
        endif
      endif

      set state to 1

    elseif ( OnKeyDown 28 )  ; Enter - ends menu same as Done
      set state to 3

    endif

  elseif ( state == 3 )
    ModName "~|" StringVar
    ; include any code to use the string here
    set state to 0
    set button to 0
    MessageBoxEx "Congratulations, you named it %n" StringVar
  endif

End

Using the Script

The text box will appear whenever the object that the script is attached to is Activated. So either place the Activator somewhere that the player will see and activate it, or use this code:

ActivatorRef.Activate player 1

Further, the final block of code should be modified for your needs. It is important to remove the trailing tilde and reset the two short variables, but anything else is possible or optional.

Final Comments

This code has been thoroughly tested, and should work as long as you point StringVar to an acceptable object. Please report any bugs to the Talk page, or fix them yourself. Thank you.