1. Updated Resource Submission Rules: All model & skin resource submissions must now include an in-game screenshot. This is to help speed up the moderation process and to show how the model and/or texture looks like from the in-game camera.
    Dismiss Notice
  2. DID YOU KNOW - That you can unlock new rank icons by posting on the forums or winning contests? Click here to customize your rank or read our User Rank Policy to see a list of ranks that you can unlock. Have you won a contest and still haven't received your rank award? Then please contact the administration.
    Dismiss Notice
  3. Lead your forces to battle in the 15th Techtree Contest. The call is yours, commander!
    Dismiss Notice
  4. The reforging of the races is complete. Come see the 14th Techtree Contest Results.
    Dismiss Notice
  5. It's time to choose your horse in the race - the 32nd Modeling Contest Poll is up!
    Dismiss Notice
  6. Check out the Staff job openings thread.
    Dismiss Notice
Dismiss Notice
60,000 passwords have been reset on July 8, 2019. If you cannot login, read this.

[System] OnDoubleClick {Trackable2}

Discussion in 'Graveyard' started by dardas, May 20, 2011.

  1. dardas

    dardas

    Joined:
    Sep 12, 2008
    Messages:
    649
    Resources:
    0
    Resources:
    0
    i've made a struct that allows you to bind a trigger to a double click on a trackable,
    basicly, it uses trackable2, allthought it probably shouldn't,
    but i guess it is better for now, since it also allows me to use the event registry, and get the activating player, any how, heres the code and a example code:
    Code (vJASS):

    library OnDoubleClick requires Trackable2
        globals
            constant integer Max_Instances = 10
            //--------------------------------------------------------------
            //Max_Instances
            //
            // This value will indicate how many trackables are allowed to be followed per struct.
            // When you reach limit, it will not allow you to create any more.
        endglobals
       
        struct onDoubleClick
            private static hashtable TimerHash = InitHashtable()
            public static integer InstanceCount = 0
            public integer c
            public Trackable2 array tra[Max_Instances]
            public Event array ev[Max_Instances]
            public trigger array tri[Max_Instances]
            public timer array tim[Max_Instances]
            public real array timeout[Max_Instances]
            public boolean array two[Max_Instances]
            public player array last[Max_Instances]
           
            public Trackable2 lastTrack
            public player lastPlayer
           
            public static method create takes nothing returns thistype
                local integer this = thistype.allocate()
                set InstanceCount = InstanceCount + 1
                return this
            endmethod
           
            public method register takes trigger callback, Trackable2 listened, real timeDiffrence returns EventReg
                local trigger t = CreateTrigger()
                local EventReg r
                set c=c+1
                if c <= Max_Instances - 1 then
                    set .ev[c] = Event.create()
                    set r = ev[c].register(callback)
                    set r.data = this
                    set .tri[c] = callback
                    set .tra[c] = listened
                    set .tim[c] = CreateTimer()
                    set .timeout[c] = timeDiffrence
                    call TriggerAddCondition(t, Filter(function thistype.onClick))
                    call listened.registerClick(t)
                else
                    debug call BJDebugMsg("|c00FF0000[ERROR]|r |c000000FFonDoubleClick: |r|c0000FF00Trying to register more then " + I2S(Max_Instances) + " trackables into a single struct.|r")
                    return null
                endif
                return r
            endmethod
           
            private static method resetData takes nothing returns nothing
                local timer t = GetExpiredTimer()
                local thistype id = LoadInteger(TimerHash, GetHandleId(t), 0)
                local integer c = LoadInteger(TimerHash, GetHandleId(t), 1)
               
                set id.two[c] = false
                set id.last[c] = null
            endmethod
           
            private static method onClick takes nothing returns boolean
                local Trackable2 tracked = GetTriggeringTrackable2()
                local thistype t = 1
                local integer c = 1
                local integer co = 1
               
                loop
                exitwhen c>=InstanceCount + 1
                set t=thistype(c)
                loop
                exitwhen co>=t.c + 1
                if t.tra[co] == tracked then
                    set t.last[co]=GetTrackedPlayer()
                    set t.lastTrack=tracked
                    set t.lastPlayer=t.last[co]
                    if t.two[co] then
                        call t.ev[co].fire()
                        set t.two[co]=false
                        return false
                    endif
                    set t.two[co]=true
                    call TimerStart(t.tim[co], t.timeout[co], false, function thistype.resetData)
                    call SaveInteger(TimerHash, GetHandleId(t.tim[co]), 0, integer(t))
                    call SaveInteger(TimerHash, GetHandleId(t.tim[co]), 1, co)
                endif
                set co=co+1
                endloop
                set c=c+1
                endloop
               
               
                return false
            endmethod
        endstruct
    endlibrary
     


    The commands from onDoubleClick struct:

    Code (vJASS):

    public static method create takes nothing returns thistype
    public method register takes trigger callback, Trackable2 listened, real timeDiffrence returns EventReg
     


    in register, the returned EventReg contains the struct index, so you can use it aswell, heres an example on how to use it:
    Code (vJASS):

    library CreateHero initializer onInit uses OnDoubleClick

        private function OnDoubleClick takes nothing returns boolean
            local Trackable2 tr
            local player tp
            local integer id
            local EventReg ev
            local onDoubleClick odc
           
            //2 ways to create the unit
           
            //Option #1                                     // Okay, basicly, the 2 options
            set tr = GetTriggeringTrackable2()              // are same, its better to use first option,
            set tp = GetTrackedPlayer()                     // but if you want to use solely the
            set id = tr.userData                            // OnDoubleClick library, i'd sugguest
            call CreateUnit(tp, id, tr.X, tr.Y, tr.Facing)  // using the second option, but you must remember
            set tp = null                                   // the second option uses exactly what the first option
            //Option #2                                     // uses, its just that the second option automaticly sets
            set ev = Event.getTriggeringEventReg()          // it as variables, with Trackable2 call
            set odc = ev.data                               // while the first option is using Trackable2 callbacks directly.
            set tr = odc.lastTrack                          // I have no clue what is better to use, but thats up to you i guess..
            set tp = odc.lastPlayer                         //
            set id = tr.userData                            // Happy coding =]
            call CreateUnit(tp, id, tr.X, tr.Y, tr.Facing)  //
            set tp = null
           
            return false
        endfunction
        private function onInit takes nothing returns nothing
            local trigger t = CreateTrigger()
            local Trackable2 tr = Trackable2.create("units\\human\\HeroPaladin\\HeroPaladin.mdl",0,  0,  0,  180)
            //                                            Paladin From Human Race Model Path    x=0,y=0,z=0 facing = 180 = downwards,
            //                                                                                              downards makes it look better.
            local onDoubleClick c = onDoubleClick.create()
            set tr.userData = 'Hpal'
            call TriggerAddCondition(t, Filter(function OnDoubleClick))
            call c.register(t, tr, 0.5)
        endfunction
    endlibrary
     


    I have no clue if this actually worths behing submitted here, but atleast i'd like to get feedbacks/etc, thanks =]
     
    Last edited by a moderator: Jul 20, 2011
  2. azlier

    azlier

    Joined:
    Oct 3, 2008
    Messages:
    354
    Resources:
    4
    JASS:
    4
    Resources:
    4
    I find the way you did this to be rather strange. Can't quite figure out what's going on.

    You should make it basically a clone of DoubleClick, but for trackables. I feel that DoubleClick's method is ideal, allowing a global event with an extremely simple interface and efficient method of data attachment using TriggerExecCount. I wouldn't mind if you just copypasted the code and altered it from there.

    Use Trackable2's feature that lets you detect when any trackable is clicked anywhere. This will let you do a global event, letting the user check for specific trackables if he desires.

    You should also use Event, whether it be Jesus4Lyf's original version or the one Nestharus made. Should probably use the Jesus4Lyf version considering Trackable2 requires it anyway.

    And lastly, include a link to Trackable2 (and Event if you choose to utilize it) in the first post.
     
  3. dardas

    dardas

    Joined:
    Sep 12, 2008
    Messages:
    649
    Resources:
    0
    Resources:
    0
    I think ill remake it thru the clone you sugguested.. lol
    sorry i didnt replay, didnt have time the last week..

    Thanks for the comment..
     
  4. Bribe

    Bribe

    Joined:
    Sep 26, 2009
    Messages:
    8,198
    Resources:
    25
    Maps:
    3
    Spells:
    10
    Tutorials:
    3
    JASS:
    9
    Resources:
    25
    The code looks short enough for what it does but it also seems to add
    an unnecessary layer of complexity. If it's a double-click detection, that
    only deals with trackables, you should check your naming convention a
    little better. "onDoubleClick", for example, does not imply in its name
    that it's "On Double Click a Trackable".
     
  5. Bribe

    Bribe

    Joined:
    Sep 26, 2009
    Messages:
    8,198
    Resources:
    25
    Maps:
    3
    Spells:
    10
    Tutorials:
    3
    JASS:
    9
    Resources:
    25
    What happened to the indentation in the loop?

    The .register method should be below the method it calls from the trigger's Filter call.

    Why so many public variables?

    Why is the dynamic trigger never destroyed or nulled?

    I'm just going to graveyard this for now.