Cohadar
master of fugue
- Reaction score
- 209
JASS:
//==============================================================================
// DIALOG SYSTEM BY COHADAR -- v2.0
//==============================================================================
//
// PURPOUSE:
// * Displaying dialogs the easy way
// * Retrieving dialog results the easy way
//
//
// HOW TO USE:
// * Dialog is basically a struct wrapper around native dialog
//
// * First create a dialog,
// # local Dialog d = NewDialog()
//
// than we add a title,
// # call d.SetMessage("Some Text")
//
// and than we add couple of buttons
// # call d.AddButton("First Button", HK_A)
// # call d.AddButton("Second Button", HK_B)
// # call d.AddButton("Third", HK_C)
//
// HK_X is a hotkey constant for a button,
// there are constants for all letters + numbers 0..9
// hotkeys are not case-sensitive
//
// now we add a callback method for our dialog
// # call d.AddAction( function SomeFunction )
// this is the function witch will be called when a player presses a button
//
// And finally we show the dialog in one of two ways:
// # call d.ShowAll() // Displays dialog to all human players
// # call d.Show( player ) // Displays dialog to specified player
//
// Inside your callback function you can get the clicked Dialog struct like this
// local Dialog d = GetTriggerDialog()
// and then use d.GetResult() to get the hotkey of a clicked button
//
// You can also use GetTriggerPlayer() to find out witch player pressed the button
//
// PROS:
// * Extremelly easy to use compared to native dialogs
// * It is fool-proof and will warn you if you try to do something stupid
//
// CONS:
// * You can have a maximum of 16 dialog buttons, lol
//
// DETAILS:
//
// * Don't release Dialogs before you are sure user has selected something
// I recommend to never destroy Dialogs,
// just create them when they are first time called and then show/hide them as needed
//
// REQUIREMENTS:
// * ABC v5.0
//
// HOW TO IMPORT:
// * Just create a trigger named Dialogs
// * convert it to text and replace the whole trigger text with this one
//
//==============================================================================
library Dialogs
globals
// Dialog button hotkey constants
constant integer HK_ESC = 512
constant integer HK_0 = 48
constant integer HK_1 = 49
constant integer HK_2 = 50
constant integer HK_3 = 51
constant integer HK_4 = 52
constant integer HK_5 = 53
constant integer HK_6 = 54
constant integer HK_7 = 55
constant integer HK_8 = 56
constant integer HK_9 = 57
constant integer HK_A = 65
constant integer HK_B = 66
constant integer HK_C = 67
constant integer HK_D = 68
constant integer HK_E = 69
constant integer HK_F = 70
constant integer HK_G = 71
constant integer HK_H = 72
constant integer HK_I = 73
constant integer HK_J = 74
constant integer HK_K = 75
constant integer HK_L = 76
constant integer HK_M = 77
constant integer HK_N = 78
constant integer HK_O = 79
constant integer HK_P = 80
constant integer HK_Q = 81
constant integer HK_R = 82
constant integer HK_S = 83
constant integer HK_T = 84
constant integer HK_U = 85
constant integer HK_V = 86
constant integer HK_W = 87
constant integer HK_X = 88
constant integer HK_Y = 89
constant integer HK_Z = 90
endglobals
globals
private constant integer MAX_BUTTONS = 16 // maximum of buttons on dialog
endglobals
//===========================================================================
// Use this inside dialog action function
//===========================================================================
function GetTriggerDialog takes nothing returns Dialog
return GetDialogStructA(GetClickedDialog())
endfunction
//===========================================================================
struct Dialog
private trigger t = CreateTrigger()
private dialog d = DialogCreate()
private boolean isActionSet = false
private string messageText = ""
private integer button_count = 0
private button array buttons[MAX_BUTTONS]
private integer array hotkeys[MAX_BUTTONS]
static method create takes nothing returns Dialog
local Dialog ret = Dialog.allocate()
call TriggerRegisterDialogEvent( ret.t, ret.d )
call SetDialogStructA(ret.d, ret)
return ret
endmethod
method onDestroy takes nothing returns nothing
call DestroyTrigger(.t)
call ClearDialogStructA(.d)
call DialogDestroy(.d)
endmethod
method GetResult takes nothing returns integer
local button b = GetClickedButton()
local integer i = 0
loop
exitwhen i >= MAX_BUTTONS
if b == this.buttons<i> then
return this.hotkeys<i>
endif
set i = i + 1
endloop
call BJDebugMsg("|c00FF0000ERROR: Unknown dialog hotkey")
return 0
endmethod
method SetMessage takes string messageText returns nothing
set .messageText = messageText
endmethod
method AddButton takes string buttonText, integer hotkey returns nothing
local button b
if this.button_count >= MAX_BUTTONS then
call BJDebugMsg("|c00FF0000ERROR: Maximum number of dialog buttons is " + I2S(MAX_BUTTONS))
else
set b = DialogAddButton( this.d, buttonText , hotkey )
set this.buttons[this.button_count] = b
set this.hotkeys[this.button_count] = hotkey
set this.button_count = this.button_count + 1
endif
endmethod
method AddAction takes code actionFunc returns nothing
if this.isActionSet == true then
call BJDebugMsg("|c00FF0000ERROR: Dialog.AddAction - you cannot set more than one dialog action")
else
set this.isActionSet = true
call TriggerAddAction( this.t, actionFunc )
endif
endmethod
method Show takes player whichPlayer returns nothing
if this.isActionSet == false then
call BJDebugMsg("|c00FF0000WARNING: You forgot to set a dialog action")
endif
if this.button_count == 0 then
call BJDebugMsg("|c00FF0000ERROR: You cannot show dialog with no buttons")
else
// message must be set before every display because of some bug.
call DialogSetMessage( this.d, this.messageText )
call DialogDisplay(whichPlayer, this.d, true)
endif
endmethod
method ShowAll takes nothing returns nothing
local integer i = 0
loop
exitwhen i>=12 // maximum of human players is 12
if GetPlayerController(Player(i)) == MAP_CONTROL_USER and GetPlayerSlotState(Player(i)) == PLAYER_SLOT_STATE_PLAYING then
call this.Show(Player(i))
endif
set i = i + 1
endloop
endmethod
method Hide takes player whichPlayer returns nothing
call DialogDisplay(whichPlayer, this.d, false)
endmethod
method HideAll takes nothing returns nothing
local integer i = 0
loop
exitwhen i>=12 // maximum of human players is 12
call this.Hide(Player(i))
set i = i + 1
endloop
endmethod
endstruct
endlibrary
</i></i>
JASS:
//===========================================================================
//
// Here is a small example how to use Dialog system.
// You need 3 things for every Dialog.
//
// 1. global Dialog variable set to zero
// 2. trigger action that will create Dialog on first use and display it
// 3. dialog Callback that will handle Dialog results
//
/// Dialog system is based on hotkeys, you must assign a different hotkey
// to each button you add to a Dialog.
// This hotkeys are at the same time a keybord shortcuts for your dialog buttons
// and a numeric result of your dialog.
//
//===========================================================================
scope yn
globals
// always initialize global Dialogs with zero
// so you can check that on first use
Dialog ynDialog = 0
endglobals
//===========================================================================
private function Callback takes nothing returns nothing
local integer result = GetTriggerDialog().GetResult()
if result == HK_Y then
call BJDebugMsg("Yes please.")
elseif result == HK_N then
call BJDebugMsg("No tnx.")
elseif result == HK_ESC then
return
else
// This should never happen, but it is a good idea to check it
// Just in case we add/remove some buttons and then forget to update Callback
call BJDebugMsg("ERROR: Callback UNKNOWN RESULT #" + I2S(result))
endif
endfunction
//===========================================================================
private function Actions takes nothing returns nothing
// create Dialog on first use
if ynDialog == 0 then
set ynDialog = Dialog.create()
call ynDialog.SetMessage("You Need More Explaining?")
call ynDialog.AddButton("Yes", HK_Y)
call ynDialog.AddButton("No", HK_N)
call ynDialog.AddButton("Cancel", HK_ESC)
call ynDialog.AddAction( function Callback )
endif
call ynDialog.Show(GetTriggerPlayer())
endfunction
//===========================================================================
public function InitTrig takes nothing returns nothing
local trigger trig = CreateTrigger()
call TriggerRegisterPlayerChatEvent(trig, Player(0),"-yn", true)
call TriggerAddAction( trig, function Actions )
endfunction
endscope
Download the test map, there is something interesting there.
if you don't you will be sorry for the rest of your lives.