Official ScriptUO EasyUO Scripts > Scripting Tutorials
Creating a user interface, step by step
TrailMyx:
There seems to be a lot of confusion about how user interfaces work in EasyUO. Actually there are many ways to implement these, so in this example I will describe creating a UI that will:
1) Continuously scan for user input
2) Continuously update the user interface for changing information.
The initial structure:
Script flow is important when setting up a user interface. You don't want to call a menu item constructor more than once, so typically you will have one routine that will draw your entire user interface panel. After the initial drawing, you may delete/add menu items as the script runs. The code generated by the EasyUO Menu Designer lends itself perfectly to this method since all the necessary code to draw your newly created UI is located in one sub typicall named showEUOMenu1.
So here is the basic layout of a user interfaced script:
1) Setup your UI panel (typically a call to showEUOMenu1 or your own UI code)
2) Setup of your variables used for your script.
3) Main loop starts here
4) Update UI information (handling input read (menu get) from UI controls via #MENURES
5) Sample UI input from #MENUBUTTON
6) If #MENUBUTTON <> N/A, then handle this button action (possibly 1+ function per button action)
7) Housekeeping routines
8 ) Loop back to Main loop
Here is an example script which I wrote specifically for this tutorial:
--- Code: easyuo ---;=================================================================; Script Name: TrailMyx's UI Tutorial - Spellcasting; Author: TrailMyx; Version: 0.68; Shard OSI / FS: OSI / FS OK; Revision Date: 9/29/2007;; Purpose:;; Globals/System variables:;; Special Thanks:;; Revision History:;gosub showEUOMenu1gosub Setupset #MENUBUTTON N/A set %current_circle 1set %current_log_selection 0set %last_target N/A mainloop1:;; Update Window; gosub UpdateLogWindow menu get CircleMenu if #MENURES <> %current_circle { set %current_circle #MENURES gosub UpdateSpellMenu %current_circle } menu get EUOListLogWindow if #MENURES <> %current_log_selection { set %current_log_selection #MENURES set %temp %journal . %current_log_selection menu set EUOStatus %temp };; Handle Buttons/Checkmarks; if #MENUBUTTON = EUOButtonCast { set #MENUBUTTON N/A ; Always remember to reset #MENUBUTTON when you handle it! menu delete EUOShape1 menu Shape EUOShape1 168 40 105 21 3 7 1 Black 7 Red menu get CircleMenu set %circle #MENURES menu get SpellMenu set %spell #MENURES menu get EUOCheckWaitForTarget set %waitfortarget #MENURES if %circle = 9 ; Computer the event macro 15 spell number... set %spell_num 100 + %spell else set %spell_num ( ( %circle - 1 ) * 8 ) + %spell - 1 event macro 15 %spell_num if %waitfortarget = #TRUE { target 10s if %last_target = N/A { repeat until #TARGCURS = 0 set %last_target #LTARGETID } event macro 22 0 } menu get EUOEditDelay wait #MENURES menu delete EUOShape1 menu Shape EUOShape1 168 40 105 21 3 7 1 Black 7 Lime } if #MENUBUTTON = EUOButtonResetTarget { set #MENUBUTTON N/A ; Always remember to reset #MENUBUTTON when you handle it! set %last_target N/A } menu get EUOCheckLoop if #MENURES = #TRUE { set #MENUBUTTON EUOButtonCast ; Force the Cast button to be pressed again! }goto mainloop1;--------------------------------------------------------------sub Setup menu Combo Add CircleMenu First Circle menu Combo Add CircleMenu Second Circle menu Combo Add CircleMenu Third Circle menu Combo Add CircleMenu Forth Circle menu Combo Add CircleMenu Fifth Circle menu Combo Add CircleMenu Sixth Circle menu Combo Add CircleMenu Seventh Circle menu Combo Add CircleMenu Eighth Circle menu Combo Add CircleMenu Necromancy Circle menu Combo Select CircleMenu 1 ; select 1st circle gosub UpdateSpellMenu 1 ; redraw combo SpellMenu with 1st circle spells menu Combo Select SpellMenu 1 ; always select the first combo select so it's visiblereturn;--------------------------------------------------------------sub UpdateSpellMenu set %circle %1 menu Delete SpellMenu menu Font BGColor White menu Combo Create SpellMenu 12 64 145 menu get EUOCheckOSI set %shard_kind #MENURES ; OSI and RunUO have different spells for 1st if %circle = 1 { if %shard_kind = #TRUE { menu Combo Add SpellMenu Clumsy menu Combo Add SpellMenu Create Food menu Combo Add SpellMenu Feeblemind menu Combo Add SpellMenu Heal menu Combo Add SpellMenu Magic Arrow menu Combo Add SpellMenu Night Sight menu Combo Add SpellMenu Reactive Armor menu Combo Add SpellMenu Weaken } else { menu Combo Add SpellMenu Reactive Armor menu Combo Add SpellMenu Clumsy menu Combo Add SpellMenu Create Food menu Combo Add SpellMenu Feeblemind menu Combo Add SpellMenu Heal menu Combo Add SpellMenu Magic Arrow menu Combo Add SpellMenu Night Sight menu Combo Add SpellMenu Weaken } return } if %circle = 2 { menu Combo Add SpellMenu Agility menu Combo Add SpellMenu Cunning menu Combo Add SpellMenu Cure menu Combo Add SpellMenu Harm menu Combo Add SpellMenu Magic Trap menu Combo Add SpellMenu Magic Untrap menu Combo Add SpellMenu Protection menu Combo Add SpellMenu Strength } if %circle = 3 { menu Combo Add SpellMenu Bless menu Combo Add SpellMenu Fireball menu Combo Add SpellMenu Magic Lock menu Combo Add SpellMenu Poison menu Combo Add SpellMenu Telekinesis menu Combo Add SpellMenu Teleport menu Combo Add SpellMenu Unlock menu Combo Add SpellMenu Wall of Stone } if %circle = 4 { menu Combo Add SpellMenu Arch Cure menu Combo Add SpellMenu Arch Protection menu Combo Add SpellMenu Curse menu Combo Add SpellMenu Fire Field menu Combo Add SpellMenu Greater Heal menu Combo Add SpellMenu Lightning menu Combo Add SpellMenu Mana Drain menu Combo Add SpellMenu Recall } if %circle = 5 { menu Combo Add SpellMenu Blade Spirits menu Combo Add SpellMenu Dispel Field menu Combo Add SpellMenu Incognito menu Combo Add SpellMenu Magic Reflection menu Combo Add SpellMenu Mind Blast menu Combo Add SpellMenu Paralyze menu Combo Add SpellMenu Poison Field menu Combo Add SpellMenu Summon Creature } if %circle = 6 { menu Combo Add SpellMenu Dispel menu Combo Add SpellMenu Energy Bolt menu Combo Add SpellMenu Explosion menu Combo Add SpellMenu Invisibility menu Combo Add SpellMenu Mark menu Combo Add SpellMenu Mass Curse menu Combo Add SpellMenu Paralyze Field menu Combo Add SpellMenu Reveal } if %circle = 7 { menu Combo Add SpellMenu Chain Lightning menu Combo Add SpellMenu Energy Field menu Combo Add SpellMenu Flame Strike menu Combo Add SpellMenu Gate Travel menu Combo Add SpellMenu Mana Vampire menu Combo Add SpellMenu Mass Dispel menu Combo Add SpellMenu Meteor Swarm menu Combo Add SpellMenu Polymorph } if %circle = 8 { menu Combo Add SpellMenu Earthquake menu Combo Add SpellMenu Energy Vortex menu Combo Add SpellMenu Resurrection menu Combo Add SpellMenu Air Elemental menu Combo Add SpellMenu Summon Daemon menu Combo Add SpellMenu Earth Elemental menu Combo Add SpellMenu Fire Elemental menu Combo Add SpellMenu Water Elemental } if %circle = 9 { menu Combo Add SpellMenu Animate Dead menu Combo Add SpellMenu Blood Oath menu Combo Add SpellMenu Corpse Skin menu Combo Add SpellMenu Curse Weapon menu Combo Add SpellMenu Evil Omen menu Combo Add SpellMenu Horrific Beast menu Combo Add SpellMenu Lich Form menu Combo Add SpellMenu Mind Rot menu Combo Add SpellMenu Pain Spike menu Combo Add SpellMenu Poison Strike menu Combo Add SpellMenu Strangle menu Combo Add SpellMenu Summon Familiar menu Combo Add SpellMenu Vampiric Embrace menu Combo Add SpellMenu Vengeful Spirit menu Combo Add SpellMenu Wither menu Combo Add SpellMenu Wraith Form menu Combo Add SpellMenu Exorcism }return;--------------------------------------------------------------sub UpdateLogWindow if %jindex = N/A set %jindex #JINDEX if %journal_pointer = N/A set %journal_pointer 1 if %journal_pointer > 200 { set %journal_pointer 1 menu delete EUOListLogWindow ; remember when you want to redraw a control, you MUST!! delete it first. menu List Create EUOListLogWindow 12 136 257 225 } while %jindex < #JINDEX { scanjournal %jindex gosub AddSpace #JOURNAL menu List add EUOListLogWindow #RESULT set %journal . %journal_pointer #RESULT set %journal_pointer %journal_pointer + 1 set %jindex %jindex + 1 } return;--------------------------------------------------------------; %1 - string to mungsub AddSpace namespace push namespace local AS set !tempstring %1 AddSpace_loop1: str pos !tempstring _ if #STRRES <> 0 { set !val #STRRES - 1 str left !tempstring !val set !left #STRRES set !val !val + 1 str del !tempstring 1 !val set !tempstring !left , #SPC , #STRRES goto AddSpace_loop1 } set #RESULT !tempstring namespace popreturn #RESULT;--------------------------------------------------------------sub UpdateNecromancySpellMenu menu Delete SpellMenu menu Combo Create SpellMenu 12 20 145 menu Combo Add SpellMenu Animate Dead menu Combo Add SpellMenu Blood Oath menu Combo Add SpellMenu Corpse Skin menu Combo Add SpellMenu Curse Weapon menu Combo Add SpellMenu Evil Omen menu Combo Add SpellMenu Horrific Beast menu Combo Add SpellMenu Lich Form menu Combo Add SpellMenu Mind Rot menu Combo Add SpellMenu Pain Spike menu Combo Add SpellMenu Poison Strike menu Combo Add SpellMenu Strangle menu Combo Add SpellMenu Summon Familiar menu Combo Add SpellMenu Vampiric Embrace menu Combo Add SpellMenu Vengeful Spirit menu Combo Add SpellMenu Wither menu Combo Add SpellMenu Wraith Form menu Combo Add SpellMenu Exorcismreturn;--------- EasyUO Menu Designer Code Begin ---------sub showEUOMenu1 menu Clear menu Window Title TrailMyx's Spell Caster menu Window Color BtnFace menu Window Size 277 392 menu Font Transparent #true menu Font Align Right menu Font Name MS Sans Serif menu Font Size 8 menu Font Style menu Font Color WindowText menu Font Transparent #false menu Font Align Left menu Text EUOLabel1 8 4 Spell circle/Necro: menu Text EUOLabel2 8 48 Spell name: menu Text EUOLabel3 8 120 Log Display: menu Shape EUOShape1 168 40 105 21 3 7 1 Black 7 Lime menu Text EUOLabel4 16 96 Delay menu Font BGColor Window menu Combo Create CircleMenu 12 20 145 menu Combo Create SpellMenu 12 64 145 menu List Create EUOListLogWindow 12 136 257 225 menu Font BGColor BtnFace menu Button EUOButtonCast 184 12 75 25 Cast menu Check EUOCheckOSI 172 64 73 17 #true OSI menu Font BGColor Window menu Edit EUOStatus 12 368 257 ... menu Font BGColor BtnFace menu Check EUOCheckLoop 172 80 93 17 #false Loop? menu Check EUOCheckWaitForTarget 172 96 109 17 #false Wait for Target? menu Font BGColor Window menu Edit EUOEditDelay 48 92 81 20 menu Font BGColor BtnFace menu Button EUOButtonResetTarget 184 116 75 21 Reset Target menu Show 421 270return;--------- EasyUO Menu Designer Code End ---------
Here is a VERY simplified version of what this script does (psudocode)
--- Code: easyuo ---gosub showEUOMenu1 ; build and show showEUOMenu1 menu (generated with Menu Designer)gosub Setup ; setup menu informationmainloop1: gosub UpdateLogWindow [i]if MenuCircle has changed[/i] gosub UpdateSpellMenu %current_circle [i]if EUOListLogWindow selection has changed Get currently selected item in EUOListLogWindow Set this value as text within EUOStatus [/i] if #MENUBUTTON = EUOButtonCast [i]Cast the spell[/i] if #MENUBUTTON = EUOButtonResetTarget set %last_target N/A menu get EUOCheckLoop if #MENURES = #TRUE set #MENUBUTTON EUOButtonCast ; force the casting of the last spell goto mainloop1
So we talked about the menu, and here it is:
--- Quote ---;--------- EasyUO Menu Designer Code Begin ---------
sub showEUOMenu1
menu Clear
menu Window Title TrailMyx's Spell Caster
menu Window Color BtnFace
menu Window Size 277 392
menu Font Transparent #true
menu Font Align Right
menu Font Name MS Sans Serif
menu Font Size 8
menu Font Style
menu Font Color WindowText
menu Font Transparent #false
menu Font Align Left
menu Text EUOLabel1 8 4 Spell circle/Necro:
menu Text EUOLabel2 8 48 Spell name:
menu Text EUOLabel3 8 120 Log Display:
menu Shape EUOShape1 168 40 105 21 3 7 1 Black 7 Lime
menu Text EUOLabel4 16 96 Delay
menu Font BGColor Window
menu Combo Create CircleMenu 12 20 145
menu Combo Create SpellMenu 12 64 145
menu List Create EUOListLogWindow 12 136 257 225
menu Font BGColor BtnFace
menu Button EUOButtonCast 184 12 75 25 Cast
menu Check EUOCheckOSI 172 64 73 17 #true OSI
menu Font BGColor Window
menu Edit EUOStatus 12 368 257 ...
menu Font BGColor BtnFace
menu Check EUOCheckLoop 172 80 93 17 #false Loop?
menu Check EUOCheckWaitForTarget 172 96 109 17 #false Wait for Target?
menu Font BGColor Window
menu Edit EUOEditDelay 48 92 81 20
menu Font BGColor BtnFace
menu Button EUOButtonResetTarget 184 116 75 21 Reset Target
menu Show 421 270
return
;--------- EasyUO Menu Designer Code End ---------
--- End quote ---
You can see that there are a few different menu elements that we'll need to manipulate, but there are several that will effect the script flow so we'll concentrate on:
menu combo
menu list
menu check
menu edit
First, I'll discuss a bit more of what's happening in the main loop. For the first button item EUOButtonCast, there are some items you should be aware of. First is that when I'm casting a spell, I change the "green" box into a "red" box. Unfortunately with EasyUO, there's no way to change the drawing attributes of an items that's already drawn. The only thing you can do is to delete the item, and redraw it with the correct color/font/background. So this code:
--- Code: easyuo --- menu delete EUOShape1 menu Shape EUOShape1 168 40 105 21 3 7 1 Black 7 Red
will delete the "green" box and redraw the box as "red" It's IMPORTANT to say again that you should always delete the existing item, otherwise you'll be accumulating unused drawing objects in your UI which will impact your performance and possibily crash EasyUO in time.
The next important point I'd like to make here is that every time you handle a valid #MENUBUTTON press, you should reset the #MENUBUTTON value to some unknown value. I generally use "N/A" and I do this right after the condition:
--- Code: easyuo --- if #MENUBUTTON = EUOButtonCast { set #MENUBUTTON N/A ; Always remember to reset #MENUBUTTON when you handle it!...
When you are looking at controls on the UI, there's only one method you can retrieve information from them (2 if you include buttons). #MENURES holds the value of any "menu get" command issued. So this code:
--- Code: easyuo --- menu get CircleMenu set %circle #MENURES menu get SpellMenu set %spell #MENURES menu get EUOCheckWaitForTarget set %waitfortarget #MENURES
Retrieves the values of the ComboBoxes CircleMenu and SpellMenu as well as the CheckBox EUOCheckWaitForTarget. ListBox and ComboBox #MENURES values start at 1 for the first selection and so forth. A #MENURES of 0 means there's nothing selected
But you see in the above code, we have to read the value of the control, then store that value in a variable in order to check more than one control at a time.
Dynamic UI Information
You'll notice when you run this script, that when you change the Circle number, you change the menu selections for the SpellMenu. I've included this function because there are some annoying quirks to using ComboBoxes and ListBoxes within EasyUO. These are the quirks I'm talking about:
1) You cannot read the text from a Combo/List box, only the index
2) You cannot DELETE an item from a Combo/List box.
The second one is totally annoying when you are trying to manipulate the contents of one of these Boxes. In order to delete information from a Combo/List box, you have to completely re-draw the entire control. Yes, you have to delete it, and then add back all the information that was originally contained but omitting the information you wanted to delete. Kinda dumb? Yes, I think so to. However, it's what we have to work with, so I have implemented code in this sample script to help you understand that.
Here is how you first add information to a List/Combo box:
--- Code: easyuo --- menu Combo Add CircleMenu First Circle menu Combo Add CircleMenu Second Circle menu Combo Add CircleMenu Third Circle menu Combo Add CircleMenu Forth Circle menu Combo Add CircleMenu Fifth Circle menu Combo Add CircleMenu Sixth Circle menu Combo Add CircleMenu Seventh Circle menu Combo Add CircleMenu Eighth Circle menu Combo Add CircleMenu Necromancy Circle menu Combo Select CircleMenu 1 ; select 1st circle...
Using a script, you can select which item in the list you want to have highlighted with the "menu Combo Select ControlName" command. Otherwise this value will be zero and you won't have an item selected until you do it by hand during script execution.
In the sub UpdateSpellMenu function, you can see what I'm talking about when you have to redraw a List/Combo control with different information:
--- Code: easyuo --- menu Delete SpellMenu menu Font BGColor White menu Combo Create SpellMenu 12 64 145 menu get EUOCheckOSI set %shard_kind #MENURES ; OSI and RunUO have different spells for 1st if %circle = 1 { if %shard_kind = #TRUE { menu Combo Add SpellMenu Clumsy menu Combo Add SpellMenu Create Food menu Combo Add SpellMenu Feeblemind menu Combo Add SpellMenu Heal menu Combo Add SpellMenu Magic Arrow menu Combo Add SpellMenu Night Sight menu Combo Add SpellMenu Reactive Armor menu Combo Add SpellMenu Weaken }...
We delete the whole control SpellMenu:
--- Code: easyuo --- menu Delete SpellMenu
then create another exact copy with the same dimensions:
--- Code: easyuo --- menu Combo Create SpellMenu 12 64 145
Then you just add the information back that you want to be included in the control.
You'll notice that this script logs anything that happens in the journal to the EUOListLogWindow ListBox. The function UpdateLogWindow also maintains a record of the text contained in this list box since the ListBox control doesn't do this for you. That way, when you click of of the items in the EUOListLogWindow control, that value is copied to the EUOStatus EditBox.
--- Code: easyuo ---;--------------------------------------------------------------sub UpdateLogWindow if %jindex = N/A set %jindex #JINDEX if %journal_pointer = N/A set %journal_pointer 1 if %journal_pointer > 200 { set %journal_pointer 1 menu delete EUOListLogWindow ; remember when you want to redraw a control, you MUST!! delete it first. menu List Create EUOListLogWindow 12 136 257 225 } while %jindex < #JINDEX { scanjournal %jindex gosub AddSpace #JOURNAL menu List add EUOListLogWindow #RESULT set %journal . %journal_pointer #RESULT set %journal_pointer %journal_pointer + 1 set %jindex %jindex + 1 }return
I hold the information that's shown in the journal in an array starting at index 0. I only hold 200 entries, then start over again. Specifically, that's what this code does:
--- Code: easyuo --- scanjournal %jindex gosub AddSpace #JOURNAL menu List add EUOListLogWindow #RESULT set %journal . %journal_pointer #RESULT set %journal_pointer %journal_pointer + 1 set %jindex %jindex + 1
And you get a data structure like this:
--- Quote ---%journal0 <- Journal entry 0
%journal1 <- Journal entry 1
%journal2 <- Journal entry 2
...
--- End quote ---
I make a call to AddSpace because the information contained in the #JOURNAL system variable containes underscores and not spaces, so AddSpace converts the underscores to spaces so they look better contained in the ListBox and EditBox. One thing to keep in mind at this point is:
1) #JOURNAL contains "_" for spaces
2) #PROPERTY contains spaces.
It's common for the programmer to forget this, so be sure you remember this when you are doing string comparisons between #JOURNAL and #PROPERTY entries.
valen2.0:
I cannot get that program to work that you posted to create a UI. is it broke?
The Ghost:
It work perfectly. Not sure what broken.
This is not design to get you fighting monster. It an example on how to build a menu and how to use it.
valen2.0:
I was more talking about easyuo design program. But I figured it out.
The Ghost:
can be tricky to run the first time.
Navigation
[0] Message Index
[#] Next page
Go to full version