1. The long-awaited results for Concept Art Contest #11 have finally been released!
    Dismiss Notice
  2. Join Texturing Contest #30 now in a legendary battle of mythological creatures!
    Dismiss Notice
  3. The Aftermath has been revealed for the 19th Terraining Contest! Be sure to check out the Results and see what came out of it.
    Dismiss Notice
  4. Melee Mapping Contest #3 - Results are out! Congratulate the winners and check plenty of new 4v4 melee maps designed for this competition!
    Dismiss Notice
  5. The winners of our cinematic soundtrack competition have been decided! Step by the Music Contest #11 - Results to check the entries and congratulate the winners!
    Dismiss Notice
  6. Check out the Staff job openings thread.
    Dismiss Notice

[System] ArrowKeyEvent

Discussion in 'JASS Resources' started by Bribe, Oct 19, 2011.

  1. Bribe

    Bribe

    Joined:
    Sep 26, 2009
    Messages:
    7,759
    Resources:
    25
    Maps:
    3
    Spells:
    10
    Tutorials:
    3
    JASS:
    9
    Resources:
    25
    If you want to centralize all the arrow key events in your map and keep your workload as short and sweet as possible, I have designed this library for you.

    Code (vJASS):
    library ArrowKeyEvent /*
        =========================================================================
        ArrowKeyEvent version 1.2.0.0
        =========================================================================
        Credits:
        -------------------------------------------------------------------------
        -   Written by Bribe.
        -   Earth-Fury for providing a lot of inspiration for the development of
            this system (especially documentation) via his KeyAction resource.
        -   tooltiperror & Sgqvur for providing very helpful, constructive advice.
        -   SA Dashie for the functionality to enable/disable an individual module
            event.
        =========================================================================
        Introduction:
        -------------------------------------------------------------------------
        Easy to use, efficient system for handling all arrow key events. It uses
        arrays and GetHandleId lookups to avoid the trap of many cloned functions
        that so many arrow key systems suffer from.
        =========================================================================
        API Guide:
        -------------------------------------------------------------------------
        To help centralize and make everything understandable, I originally used
        the constants appointed by Blizzard (bj_KEYEVENTKEY_LEFT/RIGHT/etc). But
        there was a lot of criticism over their ugliness so I made the following
        constants to correspond accordingly. They have the same values as the BJ
        constants, so you can use whichever is more appealing for you.

        Their purpose is to be passed as arguments so you are able to query such
        things as "is this key pressed" or simply to help make sense of what key
        was pressed from an event response and interpret it as an integer.

            constant integer ARROW_KEY_LEFT  = 0
            constant integer ARROW_KEY_RIGHT = 1
            constant integer ARROW_KEY_DOWN  = 2
            constant integer ARROW_KEY_UP    = 3

        -------------------------------------------------------------------------
        As I was developing this resource, it was mostly written in vanilla JASS.
        I had since converted it to OOP syntax but it has been requested to bring
        it back. I have made it available once again.

        function IsArrowKeyPressed
            takes player whichPlayer, integer arrowKey
                returns boolean

            To find out if the arrow key was pressed, you need to first ask which
            player is holding down the key, and then pass an ARROW_KEY constant
            to represent the key you are querying for.

        function RegisterArrowKeyEvent
            takes code onEvent
                returns nothing

            Instead of making up to 8 different functions for 8 different events,
            you can use this instead. Just specify a function that you want to be
            called whenever any key is pressed. For event responses, reference 1
            of the following 3 functions:

        function GetEventArrowKeyPlayerId
            takes nothing
                returns integer

            This is more of an optimization benefit than not. GetTriggerPlayer()
            will get you the player who pressed the key, but most of the time you
            just need to know the player ID of that person.

        function GetEventArrowKey
            takes nothing
                returns integer

            Call this function to find out which key was pressed. It will return
            one of the four ARROW_KEY constants, of course.

        function IsEventArrowKeyPressed
            takes nothing
                returns boolean

            This is also here more for optimization's benefit. You can certainly
            use "IsArrowKeyPressed(GetEventArrowKey(GetEventArrowKeyPlayerId()))"
            but this is much more convenient I must say.

        -------------------------------------------------------------------------
        "implement ArrowKey"

        ArrowKey API is accessible as if it were part of the implementing struct
        itself. As a bonus, you can create a method "onArrowKeyEvent" that gets
        called automatically when any key is pressed. The method musn't be static,
        because the member "this" is a player ID (to mirror the ArrowKey struct's
        own API). It must take an integer as its first argument to represent the
        pressed or released key. As a final argument, it must take a boolean to
        determine if the key was pressed (true) or released (false).

        The member "this" taken by the method is a player ID.

        NEW: Each module has its own enabler of the event, either as a whole or
        for an individual player(s). This is entirely due to the work done by SA Dashie.
    */

        //=======================================================================
        //
        // System Code
        //
        //=======================================================================

        globals
            //-------------------------------------------------------------------
            // Yo dawg, I herd you like constant variables so I gave you some new
            // constant variables so you can have some constant variables to go
            // with Blizzard's constant variables.
            //
            constant integer ARROW_KEY_LEFT  = bj_KEYEVENTKEY_LEFT
            constant integer ARROW_KEY_RIGHT = bj_KEYEVENTKEY_RIGHT
            constant integer ARROW_KEY_DOWN  = bj_KEYEVENTKEY_DOWN
            constant integer ARROW_KEY_UP    = bj_KEYEVENTKEY_UP
        endglobals

        //=======================================================================
        // Ugly modules are needed to prevent initialization bugs.
        //
        private module Init
            private static method onInit takes nothing returns nothing
                local player p
                local integer i = bj_MAX_PLAYER_SLOTS
                local trigger t = .trig
                loop
                    set i = i - 1
                    set p = Player(i)
                    if GetPlayerSlotState(p) == PLAYER_SLOT_STATE_PLAYING and GetPlayerController(p) == MAP_CONTROL_USER then

                        //Register arrow key events for playing players
                        call TriggerRegisterPlayerEvent(t, p, EVENT_PLAYER_ARROW_LEFT_DOWN)
                        call TriggerRegisterPlayerEvent(t, p, EVENT_PLAYER_ARROW_LEFT_UP)
                        call TriggerRegisterPlayerEvent(t, p, EVENT_PLAYER_ARROW_RIGHT_DOWN)
                        call TriggerRegisterPlayerEvent(t, p, EVENT_PLAYER_ARROW_RIGHT_UP)
                        call TriggerRegisterPlayerEvent(t, p, EVENT_PLAYER_ARROW_DOWN_DOWN)
                        call TriggerRegisterPlayerEvent(t, p, EVENT_PLAYER_ARROW_DOWN_UP)
                        call TriggerRegisterPlayerEvent(t, p, EVENT_PLAYER_ARROW_UP_DOWN)
                        call TriggerRegisterPlayerEvent(t, p, EVENT_PLAYER_ARROW_UP_UP)

                        //Run if library ArrowKey is found in the map.
                        //! runtextmacro optional INIT_ARROW_KEY_AA()
                    endif
                    exitwhen i == 0
                endloop

                //Run if library ArrowKey is found in the map.
                //! runtextmacro optional INIT_ARROW_KEY_CALL_LINK()

                call .registerEvent(function ArrowKey.actions)
                set p = null
                set t = null
            endmethod
        endmodule

        //=======================================================================
        // A central struct to handle all ArrowKey mechanics. This has its uses,
        // giving you slightly more control over the inner system functionality.
        //
        struct ArrowKey extends array

            //-------------------------------------------------------------------
            // Event responses
            //
            readonly static integer  eventKey        = 0     //Arrow key that triggered the event.
            readonly static boolean  eventKeyPressed = false //Was the arrow key pressed?
            readonly static ArrowKey eventPlayerId   = 0     //The id of the player who pressed the key.

            //Run if library ArrowKey is found in the map.
            //! runtextmacro optional ARROW_KEY_DECLARE_ARRAYS()

            //-------------------------------------------------------------------
            // System variables
            //
            private static trigger trig = CreateTrigger()   //Handles all events.
            private static boolean array press              //Is key pressed?

            //===================================================================
            // User-friendly typecasting.
            //
            static method operator [] takes player who returns ArrowKey
                return GetPlayerId(who)
            endmethod

            //===================================================================
            // Great for simplifying arrow key events - this function runs when
            // any player presses or releases an arrow key. The code passed is
            // expected to "return false".
            //
            static method registerEvent takes code onEvent returns nothing
                call TriggerAddCondition(.trig, Filter(onEvent))
                return
            endmethod

            //===================================================================
            // Returns true if the key is pressed, false if it is released.
            //
            method isPressed takes integer arrow returns boolean
                return press[this + arrow * bj_MAX_PLAYER_SLOTS]
            endmethod

            //Run if library ArrowKey is found in the map.
            //! runtextmacro optional ARROW_KEY_AXIS_METHODS()

            //===================================================================
            // If you are running debug tests, this might come in handy.
            //
            static if DEBUG_MODE then
                static method getKeyName takes integer arrow returns string
                    if arrow == ARROW_KEY_LEFT then
                        return "LEFT"
                    elseif arrow == ARROW_KEY_RIGHT then
                        return "RIGHT"
                    elseif arrow == ARROW_KEY_DOWN then
                        return "DOWN"
                    elseif arrow == ARROW_KEY_UP then
                        return "UP"
                    endif
                    return "--"
                endmethod
            endif

            //===================================================================
            //
            // Private Components
            //
            //===================================================================

            //===================================================================
            // Key event handler.
            //
            private static method actions takes nothing returns nothing
                local integer id = GetHandleId(GetTriggerEventId()) - 261 //Still the same eventID in 1.29
                set .eventPlayerId = GetPlayerId(GetTriggerPlayer())

                //If id is an even number, the key was pressed.
                set .eventKey = id / 2
                set .eventKeyPressed = .eventKey * 2 == id
                set .press[.eventPlayerId + .eventKey * bj_MAX_PLAYER_SLOTS] = .eventKeyPressed

                //Run if library ArrowKey is found in the map.
                //! runtextmacro optional ARROW_KEY_SETUP()
            endmethod

            //Run if library ArrowKey is found in the map.
            //! runtextmacro optional INIT_ARROW_KEY_LINK()

            //Initialize the system via module
            implement Init

        endstruct

        //=======================================================================
        //
        // Event Responses
        //
        //=======================================================================

        //=======================================================================
        function IsArrowKeyPressed takes player whichPlayer, integer arrowKey returns boolean
            return ArrowKey[whichPlayer].isPressed(arrowKey)
        endfunction

        //=======================================================================
        function RegisterArrowKeyEvent takes code onEvent returns nothing
            call ArrowKey.registerEvent(onEvent)
        endfunction

        //=======================================================================
        function GetEventArrowKeyPlayerId takes nothing returns integer
            return ArrowKey.eventPlayerId
        endfunction

        //=======================================================================
        function GetEventArrowKey takes nothing returns integer
            return ArrowKey.eventKey
        endfunction

        //=======================================================================
        function IsEventArrowKeyPressed takes nothing returns boolean
            return ArrowKey.eventKeyPressed
        endfunction

        //=======================================================================
        // Implementation of this module allows you to make your struct "extend"
        // the ArrowKey struct. As a bonus feature, you can create a method named
        // "onArrowKeyEvent" that is called whenever a key is pressed or released.
        // The method needs "takes integer arrow, boolean pressed", and must be
        // positioned *above* the "implement ArrowKey" statement (this way it is
        // detected by the static if and doesn't compile to a function interface).
        //
        module ArrowKey

            //Delegates are fun, you should try them out.
            private delegate ArrowKey AK

            boolean enabledFor //this variable added in version 1.1.

            //===================================================================
            // This method added in version 1.1. It disables or enables the event
            // in this module for all players.
            //
            static method operator enabled= takes boolean flag returns nothing
                local integer i = bj_MAX_PLAYER_SLOTS
                loop
                    set i = i - 1
                    set thistype(i).enabledFor = flag
                    exitwhen i == 0
                endloop
            endmethod
            //===================================================================
            // Please call this method from *below the module implement statement
            // if you know what's good for you.
            //
            static method operator [] takes player who returns thistype
                return GetPlayerId(who)
            endmethod

            static if thistype.onArrowKeyEvent.exists then
                private static method eventProxy takes nothing returns nothing
                    local thistype this = .eventPlayerId
                    if .enabledFor then
                        call .onArrowKeyEvent(.eventKey, .eventKeyPressed)
                    endif
                endmethod
            endif

            private static method onInit takes nothing returns nothing
                local thistype i = bj_MAX_PLAYER_SLOTS
                loop
                    set i = i - 1
                    set i.AK = i    //Delegates require some delegation of course.
                    set thistype(i).enabledFor = true //Every player active at first
                    exitwhen i == 0
                endloop
                static if thistype.onArrowKeyEvent.exists then
                    call ArrowKey.registerEvent(function thistype.eventProxy)
                endif
            endmethod

        endmodule

    endlibrary


    Optional functionality add-on. If you want to make use of it, make sure your library requires ArrowKey.

    Code (vJASS):
    library ArrowKey requires ArrowKeyEvent /*
        =========================================================================
        ArrowKey version 1.0.0.0
        =========================================================================
        Credits:
        -------------------------------------------------------------------------
        Same as credits for ArrowKeyEvent
        =========================================================================
        API Guide:
        =========================================================================
        ArrowKey provides more than just event responses, it expects you to have
        some other purposes for those values. If you have an arrow-key movement
        system, for example, you might want to have certain values to know how to
        offset the unit's coordinates. The following constants provide those for
        you:

            constant integer ARROW_KEY_NEG_VALUE = -1
            constant integer ARROW_KEY_NIL_VALUE =  0
            constant integer ARROW_KEY_POS_VALUE =  1

        How you get those values in the first place is first you must query one
        of the X or Y axis, because both axis have positive and negative values
        of their own of course. You can reference these constant variables for
        that purpose:

            constant integer ARROW_KEY_X_AXIS = 0
            constant integer ARROW_KEY_Y_AXIS = 1

        I imagine you must be wondering what this is all good for. Here are the
        functions you would pass these constants into for arguments or receive as
        return values:

        function GetArrowKeyAxis
            takes integer arrowKey
                returns integer

            Pass an ARROW_KEY_LEFT/RIGHT/etc. constant to this function to return
            the axial constant they correspond to. LEFT & RIGHT belong to the X
            axis, DOWN/UP to the Y axis of course. This is useful if you're work-
            ing with the values dynamically.

        function GetArrowKeyValue
            takes integer arrowKey
                returns integer

            I am sure you are aware that along any decent graph you have negative
            values on the left/lower axis and positive values on the right/upper
            axis. This is why this function exists. It will return -1 for down or
            left, 1 for up or right. This is very useful if you use coordinates &
            want to offset by the direction of an arrow key.

        function GetOpposingArrowKey
            takes integer arrowKey
                returns integer

            This is mostly used by the system to avoid cloned functions, but if
            you want to use it or want to know if you should use it, this simply
            returns whatever key is opposite the key you passed. LEFT for RIGHT,
            for example.

        function GetAxisArrowKey
            takes player whichPlayer, integer axis
                returns integer

            This is a really good one. First, of course you must pass a player
            argument to let the system know which player's key you want info on.
            Second, you pass it the X or Y axis value. If you want to know if the
            player is holding down the LEFT or RIGHT key, suppose they are both
            pressed? This will let you know which key was pressed LAST. If the
            last key pressed is released, but the other is still held down, this
            function intelligently knows to go back to that other key.

            If there is no key being held down, it returns the following constant:

                constant integer ARROW_KEY_NONE = -1

        function GetAxisArrowKeyValue
            takes player whichPlayer, integer axis
                returns integer

            This is a wrapper of sorts for the above function, however it filters
            out the ARROW_KEY_NONE value and returns ARROW_KEY_NIL_VALUE in that
            case. This is useful because if you are doing math you can multiply
            by 1 to go up/right, -1 to go down/left, or 0 to remain stationary on
            that axis.
    */

        //=======================================================================
        //
        // System Code
        //
        //=======================================================================

        globals
            //-------------------------------------------------------------------
            // Axis are important for a parameter in GetAxisArrowKey, a function
            // that you determine which axis key the user is focusing on.
            //
            // If no key is pressed, the value ARROW_KEY_NONE will be returned.
            //
            constant integer ARROW_KEY_X_AXIS = 0
            constant integer ARROW_KEY_Y_AXIS = 1
            constant integer ARROW_KEY_NONE   = -1

            //-------------------------------------------------------------------
            // These help to interpret arrow key values returned by the system.
            // They are very useful for coordinate-based math.
            //
            constant integer ARROW_KEY_NEG_VALUE = -1
            constant integer ARROW_KEY_NIL_VALUE =  0
            constant integer ARROW_KEY_POS_VALUE =  1
        endglobals

        function GetOpposingArrowKey takes integer arrowKey returns integer
            return ArrowKey.oppositeKey[arrowKey]
        endfunction

        function GetArrowKeyAxis takes integer arrowKey returns integer
            return ArrowKey.keyAxis[arrowKey]
        endfunction

        function GetArrowKeyValue takes integer arrowKey returns integer
            return ArrowKey.keyValue[arrowKey]
        endfunction

        function GetAxisArrowKey takes player whichPlayer, integer axis returns integer
            return ArrowKey[whichPlayer].getAxisKey(axis)
        endfunction

        function GetAxisArrowKeyValue takes player whichPlayer, integer axis returns integer
            return ArrowKey[whichPlayer].getAxisKeyValue(axis)
        endfunction

        //! textmacro ARROW_KEY_DECLARE_ARRAYS
            //-------------------------------------------------------------------
            // Useful reference variables. Pass one of the arrow key constants
            // ARROW_KEY_UP, ARROW_KEY_DOWN, ARROW_KEY_LEFT or ARROW_KEY_RIGHT.
            //
            readonly static integer array oppositeKey //Axis-opposite of key (.LEFT<->.RIGHT, .UP<->.DOWN)
            readonly static integer array keyAxis     //Axis of key (.X_AXIS or .Y_AXIS)
            readonly static integer array keyValue    //Key value (.NEG_VALUE or .POS_VALUE)

            //Needed for storing the active axis key
            private static integer array aaKey
        //! endtextmacro

        //! textmacro ARROW_KEY_AXIS_METHODS
            //===================================================================
            // Returns ARROW_KEY_NONE if there is no key pressed for that axis.
            // The return value is whatever key the user focuses on. If a player
            // holds down an arrow key, that is the active key. But if the player
            // presses the opposite key, that will be the new active key. If that
            // key is released before the other key is released, then the other
            // key will be the return value as that one is still being held down.
            //
            method getAxisKey takes integer axis returns integer
                return .aaKey[this * 2 + axis]
            endmethod

            //===================================================================
            // This method is more safe than the one above because it filters out
            // the unsafe ARROW_KEY_NONE return. It returns ARROW_KEY_NIL_VALUE
            // if there is no active key for the queried axis. I recommend this
            // method for something like an arrow key movement system because you
            // can use for seamless math.
            //
            // Example use:
            //
            //  local ArrowKey ak = ArrowKey[GetTriggerPlayer()]
            //  local real x = GetUnitX(hero[ak]) + ak.getAxisKeyValue(ArrowKey.X_AXIS) * polarOffset
            //  local real y = GetUnitX(hero[ak]) + ak.getAxisKeyValue(ArrowKey.Y_AXIS) * polarOffset
            //  call IssuePointOrder(hero[ak], "move", x, y)
            //
            method getAxisKeyValue takes integer axis returns integer
                local integer i = this.getAxisKey(axis)
                if i == ARROW_KEY_NONE then
                    return ARROW_KEY_NIL_VALUE
                endif
                return .keyValue[i]
            endmethod
        //! endtextmacro

        //! textmacro ARROW_KEY_SETUP
            if .eventKeyPressed then
                //The active axis key is the one that was just pressed.
                set id = .eventKey
            elseif .eventPlayerId.isPressed(.oppositeKey[.eventKey]) then
                //The active axis key is the opposite of this released one.
                set id = .oppositeKey[.eventKey]
            else
                //There is no active axis key.
                set id = ARROW_KEY_NONE
            endif

            //Assign the active arrow key to the player's relevant key axis.
            set .aaKey[.eventPlayerId * 2 + .keyAxis[.eventKey]] = id
        //! endtextmacro

        //! textmacro INIT_ARROW_KEY_LINK
            private static method linkKeys takes integer a, integer b, integer axis returns nothing
                set .keyAxis[a] = axis
                set .keyAxis[b] = axis
                set .keyValue[a] = ARROW_KEY_NEG_VALUE
                set .keyValue[b] = ARROW_KEY_POS_VALUE
                set .oppositeKey[a] = b
                set .oppositeKey[b] = a
            endmethod
        //! endtextmacro

        //! textmacro INIT_ARROW_KEY_AA
            //Default active axis keys to ARROW_KEY_NONE
            set .aaKey[i] = ARROW_KEY_NONE
            set .aaKey[i + 1] = ARROW_KEY_NONE
        //! endtextmacro

        //! textmacro INIT_ARROW_KEY_CALL_LINK
            call .linkKeys(ARROW_KEY_LEFT, ARROW_KEY_RIGHT, ARROW_KEY_X_AXIS)
            call .linkKeys(ARROW_KEY_DOWN, ARROW_KEY_UP, ARROW_KEY_Y_AXIS)
        //! endtextmacro

    endlibrary


    Example code
    Run it in debug mode.

    Code (vJASS):
    struct Tester extends array

        method onArrowKeyEvent takes integer arrow, boolean pressed returns nothing
            static if LIBRARY_ArrowKey then
                call BJDebugMsg("Axis Focus: X: " + .getKeyName(thistype(0).getAxisKey(ARROW_KEY_X_AXIS)) + ", Y: " + .getKeyName(thistype(0).getAxisKey(ARROW_KEY_Y_AXIS)))
            else
                if pressed then
                    call BJDebugMsg("Key pressed: " + .getKeyName(arrow))
                else
                    call BJDebugMsg("Key released: " + .getKeyName(arrow))
                endif
            endif
        endmethod

        implement ArrowKey
    endstruct
     
    Last edited: Apr 17, 2018
  2. Magtheridon96

    Magtheridon96

    Joined:
    Dec 12, 2008
    Messages:
    6,007
    Resources:
    26
    Maps:
    1
    Spells:
    8
    Tutorials:
    7
    JASS:
    10
    Resources:
    26
    Isn't using that 'Or()' thing faster than adding lots of conditions? :eek:
    Actually, I see what you did here.. these events are only going to be used in maybe 2-8 triggers max, so this is way faster ;D
    Good Job Bribe :)
     
  3. PurgeandFire

    PurgeandFire

    Code Moderator

    Joined:
    Nov 11, 2006
    Messages:
    7,419
    Resources:
    18
    Icons:
    1
    Spells:
    4
    Tutorials:
    9
    JASS:
    4
    Resources:
    18
    Check if the player is playing before you register the event for a specific player. Computers can't fire the event so it only matters for players that are playing.

    Otherwise, nothing is wrong I vote for approval. :)
     
  4. Bribe

    Bribe

    Joined:
    Sep 26, 2009
    Messages:
    7,759
    Resources:
    25
    Maps:
    3
    Spells:
    10
    Tutorials:
    3
    JASS:
    9
    Resources:
    25
    Purge, that was one of the changes I was thinking about last night as well as one mistake I made. Obviously I was one player when I tested this but if there were several -- well none of the original code would work properly.

    API change: Change the name of IsKeyPressed to IsArrowKeyPressed, added an additional paramter to pass a player ID.

    API addition: GetEventArrowKeyPlayerId.

    @Mag ForceEnumPlayersCounted probably doesn't work. So the "Or" trick is pretty useless if that's the case.

    Edit: Another API addition: IsEventArrowKeyPressed.
     
    Last edited: Oct 20, 2011
  5. Magtheridon96

    Magtheridon96

    Joined:
    Dec 12, 2008
    Messages:
    6,007
    Resources:
    26
    Maps:
    1
    Spells:
    8
    Tutorials:
    7
    JASS:
    10
    Resources:
    26
    set press[eventId * 12 + playerId] = eventId * 2 == id

    ->
    set press[id * 6 + playerId] = eventId * 2 == id


    The speed difference is extremely marginal, but hey ;P

    And it would be nice if you inline TriggerRegisterPlayerKeyEventBJ ^_^
     
  6. Bribe

    Bribe

    Joined:
    Sep 26, 2009
    Messages:
    7,759
    Resources:
    25
    Maps:
    3
    Spells:
    10
    Tutorials:
    3
    JASS:
    9
    Resources:
    25
    @Mag: do you have any idea how many lines of code that is? It would be 100% pointless to do that, save a few nanoseconds on the initialization.

    id * 6 won't work because I first need to truncate before hashing into the 2-D array, otherwise it may get conflicting array storage.
     
  7. Magtheridon96

    Magtheridon96

    Joined:
    Dec 12, 2008
    Messages:
    6,007
    Resources:
    26
    Maps:
    1
    Spells:
    8
    Tutorials:
    7
    JASS:
    10
    Resources:
    26
    Well, for inlining, all you'd have to do is this:

    Code (vJASS):
    call TriggerRegisterPlayerKeyEventBJ(trig, p, 0, j)
    call TriggerRegisterPlayerKeyEventBJ(trig, p, 1, j)


    ->

    Code (vJASS):
    // code
    call TriggerRegisterPlayerEvent(trig, p, EVENT_PLAYER_ARROW_UP_UP)
    call TriggerRegisterPlayerEvent(trig, p, EVENT_PLAYER_ARROW_UP_DOWN)
    call TriggerRegisterPlayerEvent(trig, p, EVENT_PLAYER_ARROW_DOWN_UP)
    call TriggerRegisterPlayerEvent(trig, p, EVENT_PLAYER_ARROW_DOWN_DOWN)
    call TriggerRegisterPlayerEvent(trig, p, EVENT_PLAYER_ARROW_RIGHT_UP)
    call TriggerRegisterPlayerEvent(trig, p, EVENT_PLAYER_ARROW_RIGHT_DOWN)
    call TriggerRegisterPlayerEvent(trig, p, EVENT_PLAYER_ARROW_LEFT_UP)
    call TriggerRegisterPlayerEvent(trig, p, EVENT_PLAYER_ARROW_LEFT_DOWN)


    It looks cleaner to me :p
    In fact, I might even write a RegisterPlayerEvent snippet just for this xD
     
  8. Bribe

    Bribe

    Joined:
    Sep 26, 2009
    Messages:
    7,759
    Resources:
    25
    Maps:
    3
    Spells:
    10
    Tutorials:
    3
    JASS:
    9
    Resources:
    25
    Mag, this IS a "RegisterPlayerEvent" snippet for arrow keys ;)

    I might take you up on inlining the BJ's. It's a little longer code but it is way more efficient.
     
  9. Magtheridon96

    Magtheridon96

    Joined:
    Dec 12, 2008
    Messages:
    6,007
    Resources:
    26
    Maps:
    1
    Spells:
    8
    Tutorials:
    7
    JASS:
    10
    Resources:
    26
    I was talking about a RegisterPlayerEvent for all player events :D
    ... Nah, too much work :p

    Plus, I'm already working on a Projectile system for speedfreaks and a SoundUtils update :eek:
     
  10. Bribe

    Bribe

    Joined:
    Sep 26, 2009
    Messages:
    7,759
    Resources:
    25
    Maps:
    3
    Spells:
    10
    Tutorials:
    3
    JASS:
    9
    Resources:
    25
    After making so many wrappers, even wrappers just for simple arrays, and so many unintuitive prefixes, I decided to turn this completely OOP and use a lot of readonly stuff as well.

    There is a module for "extending" the ArrowKey struct, which you can use if you prefer typing ".oppositeKey(.LEFT)" instead of "ArrowKey.oppositeKey(ArrowKey.LEFT)".

    This also has a lot more useful features now.
     
  11. Bribe

    Bribe

    Joined:
    Sep 26, 2009
    Messages:
    7,759
    Resources:
    25
    Maps:
    3
    Spells:
    10
    Tutorials:
    3
    JASS:
    9
    Resources:
    25
    Made some more changes, such as a static if for people who don't want the axis/value features.

    Anyone with experience using arrow key systems have any words on this? I am getting almost no feedback for if this is good or bad in its current state.
     
  12. Magtheridon96

    Magtheridon96

    Joined:
    Dec 12, 2008
    Messages:
    6,007
    Resources:
    26
    Maps:
    1
    Spells:
    8
    Tutorials:
    7
    JASS:
    10
    Resources:
    26
    Sorry about that Bribe :p
    This is good in it's current state:
    - The initialization is optimal
    - The system is quite fast
     
  13. Bribe

    Bribe

    Joined:
    Sep 26, 2009
    Messages:
    7,759
    Resources:
    25
    Maps:
    3
    Spells:
    10
    Tutorials:
    3
    JASS:
    9
    Resources:
    25
    Updates thanks to tooltiperrors's advice:

    - Heavily invested in the documentation.
    - Re-added function wrappers.
    - Split the library into two instead of the static if: ArrowKeyEvent and ArrowKey.
     
  14. Bribe

    Bribe

    Joined:
    Sep 26, 2009
    Messages:
    7,759
    Resources:
    25
    Maps:
    3
    Spells:
    10
    Tutorials:
    3
    JASS:
    9
    Resources:
    25
    Approved due to positive support and superior functionality than other Arrow Key systems.
     
  15. Magtheridon96

    Magtheridon96

    Joined:
    Dec 12, 2008
    Messages:
    6,007
    Resources:
    26
    Maps:
    1
    Spells:
    8
    Tutorials:
    7
    JASS:
    10
    Resources:
    26
    Code (vJASS):
            //-------------------------------------------------------------------
            // Yo dawg, I herd you like constant variables so I gave you some new
            // constant variables so you can have some constant variables to go
            // with Blizzard's constant variables.
            //


    xD
    How I love comments like this in code :D
     
  16. kStiyl

    kStiyl

    Joined:
    Oct 23, 2011
    Messages:
    180
    Resources:
    1
    JASS:
    1
    Resources:
    1
    I'm keep getting error while compiling this (after disabling debug mode)

    "Functions passed through Filter() must return boolean"

    so I made .actions return boolean false and it worked fine =)
     
  17. Bribe

    Bribe

    Joined:
    Sep 26, 2009
    Messages:
    7,759
    Resources:
    25
    Maps:
    3
    Spells:
    10
    Tutorials:
    3
    JASS:
    9
    Resources:
    25
    I noticed this yesterday and was going to make the update, the problem is that pjass sucks and Mac computers don't even run wc3 anymore let alone the fact that Intel based Macs running snow leopard no longer suffered that error
     
  18. Magtheridon96

    Magtheridon96

    Joined:
    Dec 12, 2008
    Messages:
    6,007
    Resources:
    26
    Maps:
    1
    Spells:
    8
    Tutorials:
    7
    JASS:
    10
    Resources:
    26
    Code (vJASS):
            static method registerEvent takes code onEvent returns nothing
                call TriggerAddCondition(.trig, Filter(onEvent))
            endmethod


    ->

    Code (vJASS):
            static method registerEvent takes code onEvent returns nothing
                call TriggerAddCondition(.trig, Filter(onEvent))
                return
            endmethod


    This is an easy fix :3
     
  19. Nestharus

    Nestharus

    Joined:
    Jul 10, 2007
    Messages:
    6,149
    Resources:
    8
    Spells:
    3
    Tutorials:
    4
    JASS:
    1
    Resources:
    8
    Good resource now that I think about it more =D.


    +rep ^_^
     
    Last edited: Mar 31, 2012
  20. blit_40912

    blit_40912

    Joined:
    Sep 22, 2012
    Messages:
    86
    Resources:
    0
    Resources:
    0
    Tnx for posting :D, you just gave me an idea on how do things work :D.