• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

wc3-dialogs.html

Status
Not open for further replies.
Level 13
Joined
Nov 7, 2014
Messages
571
"wc3-dialogs" is a simple .html file that tries to help with creating
"static dialogs" (dialogs as in "type dialog extends handle/agent").

By static dialog I mean one which can be created (DialogSetMessage/DialogAddButton)
at "Map Initialization" (actually just a tiny bit after that) and not
during gameplay/runtime. Think of pretty much the most boring
hero selection scheme, i.e a dialog with message: "Choose Hero" and
buttons for each of the heroes; or waypoints/teleporters selection dialog;
or game settings. In contrast a non-static (dynamic) dialog would be one
which depends on runtime information. Think of a "Kick player dialog" which
shows the players names and only those that are still in the game.

The way in which wc3-dialogs.html tries to help is by taking a concise
input in the form of JSON and then generates the "boilerplaty/verbose" [v]Jass.

The format of the input is:

JASS:
[ // we have an array of dialogs

    // each dialog has
    {
        // an identifier (variable name)
        ident: 'a_valid_jass_identifier', // optional

        // a message (the text that appears at the top of the dialog,
        // when displayed)
        // if the ident property wasn't specified
        // then it will be autogenerated from this property
        // by strining all the ' ' characters
        // in this example the ident would be (ignoring the above ident)
        // TheMessageOfTheDialog
        message: 'The Message Of The Dialog', // optional if ident was specified

        // a list of buttons
        buttons: [

            // each button has
            {
                // the text on the button
                text: 'some text',

                // those are the hotkeys that I know work
                // the letters: [A-Z],
                // the digits: [0-9]
                // and the "special" 'ESC' (which I made up)
                // it actaully has a value of 512
                hotkey: 'ESC',

                // which function to call when this button is clicked
                onclick: 'my_onclick_handle', // optional

                // which dialog to display when this button is clicked
                // display takes an 'ident'
                display: '', // optional
            },

            // more buttons
            { ... },
        ]
    },

    // more dialogs
    { ... },
]

An example input might be:

JASS:
[
    { message: 'Main Menu',
      buttons: [ { text: 'Page 1', hotkey: '1', display: 'Page1' },
                 { text: 'Page 2', hotkey: '2', display: 'Page2' },
                 { text: 'Close', hotkey: 'ESC' } ]},

    { ident: 'Page1',
      message: 'Page 1/2',
      buttons: [ { text: 'say hi', onclick: 'say_hi' },
                 { text: 'next page', hotkey: 'N', display: 'Page2' },
                 { text: 'Close', hotkey: 'ESC' }]},

    { ident: 'Page2',
      message: 'Page 2/2',
      buttons: [ { text: 'say bye', onclick: 'say_bye' },
                 { text: 'previous page', hotkey: 'P', display: 'Page1' },
                 { text: 'Close', hotkey: 'ESC' }]},
]

the generated [v]Jass (depending on the options selected) might be:

JASS:
globals
    dialog  MainMenu
    dialog  Page1
    dialog  Page2
    integer first_dialog_offset
    string  array dialogs_initial_message
    button  array dialog_btns
    integer DIALOG_HOTKEY_ESC = 512
endglobals

function dialog_get_initial_message takes dialog d returns string
    return dialogs_initial_message[GetHandleId(d) - first_dialog_offset - 0x100000]
endfunction

function dialog_display takes player p, dialog d, boolean flag returns nothing
    call DialogSetMessage(d, dialogs_initial_message[GetHandleId(d) - first_dialog_offset - 0x100000])
    call DialogDisplay(p, d, flag)
endfunction

function MainMenu_btn_0 takes nothing returns nothing
    call dialog_display(GetTriggerPlayer(), Page1, true)
endfunction

function MainMenu_btn_1 takes nothing returns nothing
    call dialog_display(GetTriggerPlayer(), Page2, true)
endfunction

function Page1_btn_0 takes nothing returns nothing
    call say_hi(Page1, GetTriggerPlayer())
endfunction

function Page1_btn_1 takes nothing returns nothing
    call dialog_display(GetTriggerPlayer(), Page2, true)
endfunction

function Page2_btn_0 takes nothing returns nothing
    call say_bye(Page2, GetTriggerPlayer())
endfunction

function Page2_btn_1 takes nothing returns nothing
    call dialog_display(GetTriggerPlayer(), Page1, true)
endfunction

function init_dialogs takes nothing returns nothing
    local trigger t

    set MainMenu = DialogCreate()
    set Page1    = DialogCreate()
    set Page2    = DialogCreate()

    set first_dialog_offset = GetHandleId(MainMenu) - 0x100000

    call DialogSetMessage(MainMenu, "Main Menu")
    set dialogs_initial_message[GetHandleId(MainMenu) - first_dialog_offset - 0x100000] = "Main Menu"
    set dialog_btns[0] = DialogAddButton(MainMenu, "Page 1", '1')
    set t = CreateTrigger()
    call TriggerRegisterDialogButtonEvent(t, dialog_btns[0])
    call TriggerAddAction(t, function MainMenu_btn_0)
    set dialog_btns[1] = DialogAddButton(MainMenu, "Page 2", '2')
    set t = CreateTrigger()
    call TriggerRegisterDialogButtonEvent(t, dialog_btns[1])
    call TriggerAddAction(t, function MainMenu_btn_1)
    set dialog_btns[2] = DialogAddButton(MainMenu, "Close", DIALOG_HOTKEY_ESC)

    call DialogSetMessage(Page1, "Page 1/2")
    set dialogs_initial_message[GetHandleId(Page1) - first_dialog_offset - 0x100000] = "Page 1/2"
    set dialog_btns[3] = DialogAddButton(Page1, "say hi", 0)
    set t = CreateTrigger()
    call TriggerRegisterDialogButtonEvent(t, dialog_btns[3])
    call TriggerAddAction(t, function Page1_btn_0)
    set dialog_btns[4] = DialogAddButton(Page1, "next page", 'N')
    set t = CreateTrigger()
    call TriggerRegisterDialogButtonEvent(t, dialog_btns[4])
    call TriggerAddAction(t, function Page1_btn_1)
    set dialog_btns[5] = DialogAddButton(Page1, "Close", DIALOG_HOTKEY_ESC)

    call DialogSetMessage(Page2, "Page 2/2")
    set dialogs_initial_message[GetHandleId(Page2) - first_dialog_offset - 0x100000] = "Page 2/2"
    set dialog_btns[6] = DialogAddButton(Page2, "say bye", 0)
    set t = CreateTrigger()
    call TriggerRegisterDialogButtonEvent(t, dialog_btns[6])
    call TriggerAddAction(t, function Page2_btn_0)
    set dialog_btns[7] = DialogAddButton(Page2, "previous page", 'P')
    set t = CreateTrigger()
    call TriggerRegisterDialogButtonEvent(t, dialog_btns[7])
    call TriggerAddAction(t, function Page2_btn_1)
    set dialog_btns[8] = DialogAddButton(Page2, "Close", DIALOG_HOTKEY_ESC)
endfunction

You would then have to copy the genearted script into your map/file and
call the init_dialogs function. You have to call it "just a tiny bit after Map Initialization"
because the DialogSetMessage native seems to be "buggy".
You can do that like so:

JASS:
    call TimerStart(CreateTimer(), 0, false, function init_dialogs)

    // or using the (equivalent?)
    // local trigger t = CreateTrigger()
    // call TriggerRegisterTimerEvent(t, 0, false)
    // call TriggerAddAction(t, function init_dialogs)

When you show a dialog to a player and he clicks a button that shows
another dialog you have to "reset" the message of the "another dialog"
(actually it's the second time you show it in which the "another dialog"'s
message "disappears"),
for some "nefarious" reason (I told you DialogSetMessage was buggy...)
that's why there's the dialog_display function which "fixes" this problem.


That's it.

PS: wc3-dialogs.html is uploaded as wc3-dialogs.txt simply rename
wc3-dialogs.txt to wc3-dialogs.html
 

Attachments

  • wc3-dialogs.txt
    39.3 KB · Views: 120
  • demo.w3x
    19.5 KB · Views: 80
Status
Not open for further replies.
Top