• 🏆 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!

function calls

Status
Not open for further replies.
Level 17
Joined
Mar 21, 2011
Messages
1,597
Hi,
i have a scope which includes several functions.
FunctionX calls FunctionY
and
FunctionY calls FunctionX
This will throw me an error of course, because both need to be at the top of each other, but how can i avoid this?

thanks
 
Level 17
Joined
Mar 21, 2011
Messages
1,597
JASS:
scope DialogSettings initializer Init 

    globals
        private button array buttons
    endglobals
    
    private function DialogEvent takes nothing returns boolean
        local Dialog  log = Dialog.getClickedDialog()
        local button  bt   = Dialog.getClickedButton()
        
        if bt == buttons[0] then
            call CreateItem('afac', 0, 0)
        elseif bt == buttons[1] then
            call CreateItem('spsh', 0, 0)
        elseif bt == buttons[2] then
            call CreateItem('ajen', 0, 0)
        elseif bt == buttons[3] then
            call CreateItem('bgst', 0, 0)
        endif
                
        call log.destroy()
        call DialogStart()
        set bt = null
        return false 
    endfunction
    
    private function DialogStart takes nothing returns nothing 
        local Dialog log = Dialog.create()
        
        set log.title  = "|cffFF7000Settings"
        set buttons[0] = log.addButton("|cff7ebff1Time [|r" + DialogTimeText[DialogTimeSetting] + "|cff7ebff1]|r", 0)
        set buttons[1] = log.addButton("|cff7ebff1Event [|r" + DialogEventText[DialogEventSetting] + "|cff7ebff1]|r", 0)
        set buttons[2] = log.addButton("|cff7ebff1Item Box [|r" + DialogItemBoxText[DialogItemBoxSetting] + "|cff7ebff1]|r", 0)
        set buttons[3] = log.addButton("|cff7ebff1Vehicle [|r" + DialogVehicleText[DialogVehicleSetting] + "|cff7ebff1]|r", 0)
        set buttons[4] = log.addButton("|cff7ebff1Area [|r" + DialogAreaText[DialogAreaSetting] + "|cff7ebff1]|r", 0)
        set buttons[5] = log.addButton("|cff20c000Ready|r", 0)
        call log.display(Player(0), true)
        call log.registerClickEvent(Condition(function DialogEvent))
        call ReleaseTimer(GetExpiredTimer())
    endfunction

    private function Init takes nothing returns nothing 
        call TimerStart(NewTimer(), 0, false, function DialogStart)
    endfunction
endscope

JASS:
library Dialog /* v.1.1.0.0
**************************************************
*
*   A struct wrapper for easy dialog creation.
*
**************************************************
*
*/  requires Table  /* [url]http://www.hiveworkshop.com/forums/jass-resources-412/snippet-new-table-188084/[/url]
* 
**************************************************
*
*   struct Dialog 
*
*       static method create() returns thistype
*           
*           Creates a new dialog and returns its instance.
*
*       method operator title= takes string s
*
*           Sets the title message for the dialog.
*
*       method addButton( string text, integer hotkey ) returns button
*
*           Adds a button to the dialog that reads <text>.
*           The hotkey serves as a shortcut to press a dialog 
*           button. Example input: 'a', 'b', 512 (esc).
*
*       method display( player p, boolean flag )
*           
*           Shows/hides a dialog for a particular player. 
*
*       method displayAll( boolean flag )
*
*           Shows/hides a dialog for all players. 
*
*       method clear()
*   
*           Clears a dialog of its message and buttons.
*
*       method destroy()
*
*           Destroys a dialog and its instance.
*
*   -- Event API --
*
*       method registerClickEvent( boolexpr b )
*
*           Registers when a dialog button is clicked.
*
*       static method getClickedDialog() returns Dialog
*       static method getClickedButton() returns button
*       static method getPlayer() returns player
*
*            Event responses.
*
**************************************************
*
*   Constants - Credits to DysfunctionaI for the list!
*/
    globals
        constant integer KEY_SPACEBAR          = 32
        
        /* Number Pad */
        constant integer KEY_NUMPAD_0          = 257
        constant integer KEY_NUMPAD_1          = 258
        constant integer KEY_NUMPAD_2          = 259
        constant integer KEY_NUMPAD_3          = 260
        constant integer KEY_NUMPAD_4          = 261
        constant integer KEY_NUMPAD_5          = 262
        constant integer KEY_NUMPAD_6          = 263
        constant integer KEY_NUMPAD_7          = 264
        constant integer KEY_NUMPAD_8          = 265
        constant integer KEY_NUMPAD_9          = 266
        constant integer KEY_NUMPAD_PLUS       = 267
        constant integer KEY_NUMPAD_MINUS      = 268
        constant integer KEY_NUMPAD_ASTERISK   = 269 
        constant integer KEY_NUMPAD_SLASH      = 270
        constant integer KEY_NUMPAD_PERIOD     = 271
        
        constant integer KEY_EQUALS            = 272
        constant integer KEY_MINUS             = 273
        constant integer KEY_LEFT_BRACKET      = 274
        constant integer KEY_RIGHT_BRACKET     = 275
        constant integer KEY_BACKSLASH         = 276
        constant integer KEY_SEMICOLON         = 277
        constant integer KEY_APOSTROPHE        = 278
        constant integer KEY_COMMA             = 279
        constant integer KEY_PERIOD            = 280   
        constant integer KEY_SLASH             = 281
        constant integer KEY_ESCAPE            = 512
        constant integer KEY_BACKSPACE         = 514
        
        /* Arrows */
        constant integer KEY_LEFT_ARROW        = 516
        constant integer KEY_UP_ARROW          = 517
        constant integer KEY_RIGHT_ARROW       = 518
        constant integer KEY_DOWN_ARROW        = 519
        
        constant integer KEY_INSERT            = 520
        constant integer KEY_DELETE            = 521
        constant integer KEY_HOME              = 522
        constant integer KEY_END               = 523
        constant integer KEY_PAGE_UP           = 524
        constant integer KEY_PAGE_DOWN         = 525
        constant integer KEY_CAPS_LOCK         = 526
        constant integer KEY_NUM_LOCK          = 527
        constant integer KEY_SCROLL_LOCK       = 528
        constant integer KEY_PAUSE             = 529
        
        /* Function Buttons */
        constant integer KEY_F1                = 768
        constant integer KEY_F2                = 769
        constant integer KEY_F3                = 770
        constant integer KEY_F4                = 771
        constant integer KEY_F5                = 772
        constant integer KEY_F6                = 773
        constant integer KEY_F7                = 774
        constant integer KEY_F8                = 775
        constant integer KEY_F9                = 776
        constant integer KEY_F10               = 777
        constant integer KEY_F11               = 778
        constant integer KEY_F12               = 779
    endglobals
/*
**************************************************/

    globals
        private Table instance = 0
    endglobals
    
    private module DialogInit 
        private static method onInit takes nothing returns nothing 
            set instance = Table.create()
        endmethod
    endmodule

    struct Dialog
        private dialog dg
        private trigger click
        private string msg
        
        static method getClickedDialog takes nothing returns thistype 
            return instance[GetHandleId(GetClickedDialog())]
        endmethod
        static method getClickedButton takes nothing returns button 
            return GetClickedButton()
        endmethod
        static method getPlayer takes nothing returns player 
            return GetTriggerPlayer()
        endmethod
        
        method operator title= takes string text returns nothing 
            call DialogSetMessage(this.dg, text)
            set this.msg = text
        endmethod
        
        method addButton takes string text, integer hotkey returns button
            return DialogAddButton(this.dg, text, hotkey)
        endmethod
        
        method display takes player p, boolean flag returns nothing
            call DialogDisplay(p, this.dg, flag)
            call DialogSetMessage(this.dg, this.msg)
        endmethod
        method displayAll takes boolean flag returns nothing
            call DialogDisplay(GetLocalPlayer(), this.dg, flag)
            call DialogSetMessage(this.dg, this.msg)
        endmethod
        
        method clear takes nothing returns nothing 
            call DialogClear(this.dg)
            set this.msg = ""
        endmethod
        
        method registerClickEvent takes boolexpr b returns nothing
            if this.click == null then
                set instance[GetHandleId(this.dg)] = this
                set this.click = CreateTrigger()
                call TriggerRegisterDialogEvent(this.click, this.dg)
            endif
            call TriggerAddCondition(this.click, b)
        endmethod
        
        method destroy takes nothing returns nothing 
            debug if this.dg == null then
            debug     call DisplayTextToPlayer(GetLocalPlayer(), 0, 0, "[Dialog] Attempted to destroy null dialog.")
            debug endif
            
            if this.click != null then
                call DestroyTrigger(this.click)
                call instance.remove(GetHandleId(this.dg))
                set this.click = null
            endif
            
            call DialogClear(this.dg)
            call DialogDestroy(this.dg)
            set this.dg = null
            call this.deallocate()
        endmethod
    
        static method create takes nothing returns thistype
            local thistype this = thistype.allocate()
            set this.dg = DialogCreate()
            return this
        endmethod
        
        implement DialogInit
    endstruct
    
endlibrary

JASS:
        /* ---------------Dialog Settings--------------- */
        set DialogItemBoxText[0] = "|cffffffffOften|r"
        set DialogItemBoxText[1] = "|cffffffffMedium|r"
        set DialogItemBoxText[2] = "|cffffffffLow|r"
        set DialogItemBoxText[3] = "|cffffffffOff|r"
        set DialogItemBoxValue[0] = 25
        set DialogItemBoxValue[1] = 50
        set DialogItemBoxValue[2] = 75
        set DialogItemBoxValue[3] = 0
        set DialogItemBoxSetting = 1
        
        set DialogTimeText[0] = "|cffffffff10 minutes|r"
        set DialogTimeText[1] = "|cffffffff15 minutes|r"
        set DialogTimeText[2] = "|cffffffff20 minutes|r"
        set DialogTimeValue[0] = 600
        set DialogTimeValue[1] = 900
        set DialogTimeValue[2] = 1200
        set DialogTimeSetting = 0
        
        set DialogEventText[0] = "|cffffffff120 seconds|r"
        set DialogEventText[1] = "|cffffffff160 seconds|r"
        set DialogEventText[2] = "|cffffffff200 seconds|r"
        set DialogEventText[3] = "|cffffffffOff|r"
        set DialogEventValue[0] = 120
        set DialogEventValue[1] = 160
        set DialogEventValue[2] = 200
        set DialogEventValue[3] = 0
        set DialogEventSetting = 1
        
        set DialogAreaText[0] = "|cffffffffBloomfield|r"
        set DialogAreaText[1] = "|cffffffffIslands|r"
        set DialogAreaValue[0] = 0
        set DialogAreaValue[1] = 1
        set DialogAreaSetting = 0
        
        set DialogVehicleText[0] = "|cffffffffOften|r"
        set DialogVehicleText[1] = "|cffffffffMedium|r"
        set DialogVehicleText[2] = "|cffffffffLow|r"
        set DialogVehicleText[3] = "|cffffffffOff|r"
        set DialogVehicleValue[0] = 170
        set DialogVehicleValue[1] = 215
        set DialogVehicleValue[2] = 260
        set DialogVehicleValue[3] = 0
        set DialogVehicleSetting = 1
        /* --------------------------------------------- */

the code is not yet finished.
i want to create a new dialog if clicked on a button where you can choose settings, and then return to the base dialog.
 
Level 19
Joined
Mar 18, 2012
Messages
1,716
If you are lazy, you can place your code into a struct.
The JassHelper creates pseudo-code if it runs into a case as presented above.
Basically it copies the functions you wish to call and places them above.

JASS:
    private struct Example
    
        private static method next takes nothing returns nothing
            if 0 == GetRandomInt(0, 10)
                call start()
            else
            
            //
            endif
        endmethod
    
        private static method start takes nothing returns nothing
            call next()
        endmethod

    endstruct
ExecuteFunc, triggers and their action and condition functions are not bound to the
order of function in you code. You would have to transfer your function arguments via
global variables.
 

Bribe

Code Moderator
Level 50
Joined
Sep 26, 2009
Messages
9,464
It's a pretty simple solution.

JASS:
Jass:  
scope DialogSettings initializer Init 

    globals
        private button array buttons
        private boolexpr bxpr
    endglobals
    
private function DialogStart takes nothing returns nothing 
        local Dialog log = Dialog.create()
        
        set log.title  = "|cffFF7000Settings"
        set buttons[0] = log.addButton("|cff7ebff1Time [|r" + DialogTimeText[DialogTimeSetting] + "|cff7ebff1]|r", 0)
        set buttons[1] = log.addButton("|cff7ebff1Event [|r" + DialogEventText[DialogEventSetting] + "|cff7ebff1]|r", 0)
        set buttons[2] = log.addButton("|cff7ebff1Item Box [|r" + DialogItemBoxText[DialogItemBoxSetting] + "|cff7ebff1]|r", 0)
        set buttons[3] = log.addButton("|cff7ebff1Vehicle [|r" + DialogVehicleText[DialogVehicleSetting] + "|cff7ebff1]|r", 0)
        set buttons[4] = log.addButton("|cff7ebff1Area [|r" + DialogAreaText[DialogAreaSetting] + "|cff7ebff1]|r", 0)
        set buttons[5] = log.addButton("|cff20c000Ready|r", 0)
        call log.display(Player(0), true)
        call log.registerClickEvent(bxpr)
        call ReleaseTimer(GetExpiredTimer())
    endfunction

    private function DialogEvent takes nothing returns boolean
        local Dialog  log = Dialog.getClickedDialog()
        local button  bt   = Dialog.getClickedButton()
        
        if bt == buttons[0] then
            call CreateItem('afac', 0, 0)
        elseif bt == buttons[1] then
            call CreateItem('spsh', 0, 0)
        elseif bt == buttons[2] then
            call CreateItem('ajen', 0, 0)
        elseif bt == buttons[3] then
            call CreateItem('bgst', 0, 0)
        endif
                
        call log.destroy()
        call DialogStart()
        set bt = null
        return false 
    endfunction

    private function Init takes nothing returns nothing 
        call TimerStart(NewTimer(), 0, false, function DialogStart)
        set bxpr = Condition(function DialogEvent)
    endfunction
endscope
 
Level 17
Joined
Mar 21, 2011
Messages
1,597
Well, the original question is now solved.

Edit: I think your issue is that you're using GetExpiredTimer() from outside a timer-expire event. This crashes the game. You should use a separate function to handle the very first initialization (the function the timer uses).

thanks ;)
yep, you are right. when i comment out the ReleaseTimer(GetExpiredTimer()), it works. I will take a closer look at it later.

Edit: Ok, makes sense ;) When i call the function a second time, i don't call it via timer and then it won't have an expired timer. Thanks for the help!

EDIT: I just replaced the direct function call with a timed function call. Is that ok? Or is the other way better?
 
Last edited:

Bribe

Code Moderator
Level 50
Joined
Sep 26, 2009
Messages
9,464
thanks ;)
yep, you are right. when i comment out the ReleaseTimer(GetExpiredTimer()), it works. I will take a closer look at it later.

Edit: Ok, makes sense ;) When i call the function a second time, i don't call it via timer and then it won't have an expired timer. Thanks for the help!

EDIT: I just replaced the direct function call with a timed function call. Is that ok? Or is the other way better?

The middle method as it sounds the simplest.
 
Level 7
Joined
Oct 19, 2015
Messages
286
Instead of replacing the direct function call with a timed one, I would do the opposite: make all function calls direct without a timer and then add a separate wrapper function that gets run by the starting timer which then calls the start function directly. This function would then release the expired timer, instead of the start function.
 
Status
Not open for further replies.
Top