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 havn't received your rank award? Then please contact the administration.
    Dismiss Notice
  3. The Lich King demands your service! We've reached the 19th edition of the Icon Contest. Come along and make some chilling servants for the one true king.
    Dismiss Notice
  4. The 4th SFX Contest has started. Be sure to participate and have a fun factor in it.
    Dismiss Notice
  5. The poll for the 21st Terraining Contest is LIVE. Be sure to check out the entries and vote for one.
    Dismiss Notice
  6. The results are out! Check them out.
    Dismiss Notice
  7. Don’t forget to sign up for the Hive Cup. There’s a 555 EUR prize pool. Sign up now!
    Dismiss Notice
  8. The Hive Workshop Cup contest results have been announced! See the maps that'll be featured in the Hive Workshop Cup tournament!
    Dismiss Notice
  9. 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.

[vJASS] [Snippet] GUI Unit Indexer -> vJass Plugin

Discussion in 'JASS Resources' started by Bribe, Aug 10, 2015.

  1. Bribe

    Bribe

    Joined:
    Sep 26, 2009
    Messages:
    8,036
    Resources:
    25
    Maps:
    3
    Spells:
    10
    Tutorials:
    3
    JASS:
    9
    Resources:
    25
    GUI Unit Indexer with vJass syntax has been realized with this groundbreaking tool. The idea for this came from the user, Spellbound.

    Note that no changes to the GUI code were needed to make this happen, so the only thing a user would need to do is import this script and make the library a requirement to libraries who call its functions. The implication of this, I suppose, is that GUI Unit Indexer can now be used for vJass resources.

    Notably different than Nestharus' API, I have included OnUnitIndex and OnUnitDeindex which are shorter to write and are not ugly. They also take a single code argument instead of a boolexpr and integer argument. The function "OnUnitDeindex" will normally fire at a random time after a unit has left the game, if you want it to fire at the instant before the unit becomes unavailable, you'll want to have the GUI Unit Event resource in your system: http://www.hiveworkshop.com/forums/spells-569/unit-event-v2-0-0-0-a-201641/

    Code (vJASS):


    library UnitIndexerGUI //requires GUI Unit Indexer
       
        globals
            private trigger index = null
            private trigger deindex = null
            private trigger init = null
            private trigger tempTrig
        endglobals

        private function DoTheThings takes trigger t, code c, real r returns trigger
            if t == null then
                set t = CreateTrigger()
                call TriggerRegisterVariableEvent(t, "udg_UnitIndexEvent", EQUAL, r)
            endif
            call TriggerAddCondition(t, Filter(c))
            set tempTrig = t
            set t = null
            return tempTrig
        endfunction

        //call RegisterUnitIndexEvent(Filter(function Blah), EVENT_UNIT_INDEXED)
        //->
        //call OnUnitIndex(function Blah)
        function OnUnitIndex takes code c returns nothing
            set index = DoTheThings(index, c, 1.)
        endfunction

        //call RegisterUnitIndexEvent(Filter(function Blah), EVENT_UNIT_DEINDEXED)
        //->
        //call OnUnitDeindex(function Blah)
        function OnUnitDeindex takes code c returns nothing
            set deindex = DoTheThings(deindex, c, 2.)
        endfunction

        private function DestroyInit takes nothing returns boolean
            call DestroyTrigger(init) //will still allow consecutive triggerconditions to run.
            set init = null
            return false
        endfunction

        //GUI Unit Indexer will initialize after any vJass stuff, so you need to do your
        //unit-indexer-requiring stuff after this event instead of a module/struct/library
        //initializer.
        function OnUnitIndexerInitialized takes code c returns nothing
            if init == null then
                set init = CreateTrigger()
                call TriggerAddCondition(init, Filter(function DestroyInit))
                call TriggerRegisterVariableEvent(init, "udg_UnitIndexEvent", EQUAL, 3.00)
            endif
            call TriggerAddCondition(init, Filter(c))
        endfunction

        function GetUnitId takes unit u returns integer
            return GetUnitUserData(u)
        endfunction

        function GetUnitById takes integer id returns unit
            return udg_UDexUnits[id]
        endfunction

        function GetIndexedUnit takes nothing returns unit
            return udg_UDexUnits[udg_UDex]
        endfunction

        function GetIndexedUnitId takes nothing returns integer
            return udg_UDex
        endfunction

        function IsUnitIndexed takes unit u returns boolean
            return udg_UDexUnits[GetUnitUserData(u)] == u
        endfunction

    endlibrary
     
     
    Last edited: Feb 15, 2016
  2. Spellbound

    Spellbound

    Joined:
    Jan 9, 2005
    Messages:
    1,953
    Resources:
    15
    Skins:
    5
    Spells:
    9
    JASS:
    1
    Resources:
    15
    Oh my, that was very quick and unexpected o_O

    My thanks to you :D

    PS:
    Code (vJASS):
    function OnUnitIndex take code c returns nothing


    missing an s.
     
  3. Bribe

    Bribe

    Joined:
    Sep 26, 2009
    Messages:
    8,036
    Resources:
    25
    Maps:
    3
    Spells:
    10
    Tutorials:
    3
    JASS:
    9
    Resources:
    25
    Thank bro
     
  4. Maker

    Maker

    Joined:
    Mar 6, 2006
    Messages:
    9,190
    Resources:
    17
    Maps:
    2
    Spells:
    14
    Tutorials:
    1
    Resources:
    17
    I have nothing constructive to say, so I'll nitpick.
    DoStuff
    is not very descriptive or professional naming :)
     
  5. PurgeandFire

    PurgeandFire

    Code Moderator

    Joined:
    Nov 11, 2006
    Messages:
    7,426
    Resources:
    18
    Icons:
    1
    Spells:
    4
    Tutorials:
    9
    JASS:
    4
    Resources:
    18
    Day 5516:

    I've just gotten back from the battlefield. Until this day, it seemed as though the war between GUI and JASS would never cease. This day... *teardrop lands onto page* GUI has struck a major blow. General Bribe and his harlots revealed a new weapon. It is a weapon so devious that my very comrades are already turning over to his side. One by one, they use his so called "plug-in". Next thing you know, they start prefixing their globals with udg_ and talking about how fast they can click through the menus. I fear that this may be the end of our dynasty. I only wish... *pen falls* *bombs echo in the distance* *Bribe's temptresses wrap their arms around the Colonel* *screen fades to black*


    (he ded)

    But on a serious note, never thought I'd see a GUI system used for vJASS. Seems fine to me apart from the name of "DoStuff" (as Maker mentioned). Should be approvable.
     
  6. Bribe

    Bribe

    Joined:
    Sep 26, 2009
    Messages:
    8,036
    Resources:
    25
    Maps:
    3
    Spells:
    10
    Tutorials:
    3
    JASS:
    9
    Resources:
    25
    Ok, it is no longer called DoStuff.
     
  7. PurgeandFire

    PurgeandFire

    Code Moderator

    Joined:
    Nov 11, 2006
    Messages:
    7,426
    Resources:
    18
    Icons:
    1
    Spells:
    4
    Tutorials:
    9
    JASS:
    4
    Resources:
    18
    Much better
     
  8. Spellbound

    Spellbound

    Joined:
    Jan 9, 2005
    Messages:
    1,953
    Resources:
    15
    Skins:
    5
    Spells:
    9
    JASS:
    1
    Resources:
    15
    Riiiiiiight, so little problem. I tried importing Bannar's ConstructEvent and for one, I was getting errors from JassHelper. So I imported the RegisterPlayerUnitEvent by Magtheridon96 and it saved without any other errors.

    Now when I try to use GetStructureBuilder(), JassHelper says not enough arguments. set udg_TempUnit = GetStructureBuilder() more specifically. A friend tested ConstructEvent on a dummy map and used TriggerHappy's indexer instead, and he was not required to have RegisterPlayerUnitEvent; set udg_TempUnit = GetStructureBuilder() also worked. So I'm assuming there are still some compatibility issues to iron out? I did replace the code in Bannar's library like you told me to in PM, Bribe, so it could be something else.

    Full Code
    Code (vJASS):

    function Trig_Taskmaster_Build_JASS_Func003Func002A takes nothing returns nothing
        call IssueTargetOrderBJ( udg_TempUnit, "smart", GetTriggerUnit() )
    endfunction

    function Trig_Taskmaster_Build_JASS_Func003C takes nothing returns boolean
        if ( not ( GetUnitTypeId(udg_TempUnit) == 'uaco' ) ) then
            return false
        endif
        if ( not ( IsUnitInGroup(udg_TempUnit, udg_Boss_group) == true ) ) then
            return false
        endif
        return true
    endfunction

    function Trig_Taskmaster_Build_JASS_Actions takes nothing returns nothing
        set udg_TempUnit = GetEventBuilder()
        call AddSpecialEffectLocBJ( GetUnitLoc(udg_TempUnit), "Abilities\\Spells\\Human\\ThunderClap\\ThunderClapCaster.mdl" )
        if ( Trig_Taskmaster_Build_JASS_Func003C() ) then
            set udg_ID = GetUnitUserData(udg_TempUnit)
            call ForGroupBJ( udg_Minion_group[udg_ID], function Trig_Taskmaster_Build_JASS_Func003Func002A )
        else
        endif
    endfunction

    //===========================================================================
    function InitTrig_Taskmaster_Build_JASS takes nothing returns nothing
        set gg_trg_Taskmaster_Build_JASS = CreateTrigger(  )
        call TriggerRegisterConstructEvent(gg_trg_Taskmaster_Build_JASS, ConstructEvent.START)
        call TriggerAddAction( gg_trg_Taskmaster_Build_JASS, function Trig_Taskmaster_Build_JASS_Actions )
    endfunction
     

    The special effect is just to know if it worked. I'll be removing it afterwards.


    PS: as a habitual GUI user, commenting in the JASS section feels like... a filthy human tracking mud in pristine elven halls :D
     
    Last edited: Aug 11, 2015
  9. PurgeandFire

    PurgeandFire

    Code Moderator

    Joined:
    Nov 11, 2006
    Messages:
    7,426
    Resources:
    18
    Icons:
    1
    Spells:
    4
    Tutorials:
    9
    JASS:
    4
    Resources:
    18
    @Spellbound: Use GetEventBuilder() as a response to the construct events. To use GetStructureBuilder, you have to pass in a structure/building.

    To summarize:
    Code (vJASS):
    GetEventBuilder() // no arguments, you just need to use it with the construct events
    GetStructureBuilder(unit) // requires you to input a unit
     
  10. Spellbound

    Spellbound

    Joined:
    Jan 9, 2005
    Messages:
    1,953
    Resources:
    15
    Skins:
    5
    Spells:
    9
    JASS:
    1
    Resources:
    15
    I have tried that already, but nothing happens. The code in my post was from the demo map and it worked. When I use it in my own map, I get missing arguments (as expected), and using GetEventBuilder() doesn't do anything. I tried with vanilla GUI events (unit begins construction) as well as
    call TriggerRegisterConstructEvent(gg_trg_Taskmaster_Build_JASS, ConstructEvent.START)
    for the JASS version and neither seems to work. I'm not sure what I'm doing wrong.
     
  11. Zwiebelchen

    Zwiebelchen

    Joined:
    Sep 17, 2009
    Messages:
    6,791
    Resources:
    12
    Models:
    5
    Maps:
    1
    Spells:
    1
    Tutorials:
    1
    JASS:
    4
    Resources:
    12
  12. Bribe

    Bribe

    Joined:
    Sep 26, 2009
    Messages:
    8,036
    Resources:
    25
    Maps:
    3
    Spells:
    10
    Tutorials:
    3
    JASS:
    9
    Resources:
    25
    The irony here is that this API is almost identical to Nestharus' first iteration of UnitIndexer, a project I was really interested in due to the fact that it was the most minimalistic approach possible. UnitIndexer now has over 9,000 requirements and lines of code (if you include static ifs and the libraries it requires, it's probably almost 9000 to be slightly less sarcastic).
     
  13. Spellbound

    Spellbound

    Joined:
    Jan 9, 2005
    Messages:
    1,953
    Resources:
    15
    Skins:
    5
    Spells:
    9
    JASS:
    1
    Resources:
    15
    Ok so I finally figured out what was going wrong and... well, I forgot to change this
    static if LIBRARY_UnitDex then
    to this
    static if LIBRARY_UnitIndexerGUI then
    .

    Derp.

    Thanks again for the plugin, Bribe :)
     
  14. Bribe

    Bribe

    Joined:
    Sep 26, 2009
    Messages:
    8,036
    Resources:
    25
    Maps:
    3
    Spells:
    10
    Tutorials:
    3
    JASS:
    9
    Resources:
    25
    Updated with IsUnitIndexed function and instructions on how to switch from RegisterUnitIndexEvent to OnUnit(Deindex/Index).

    Can a mod assess if this meets criteria?
     
  15. Bribe

    Bribe

    Joined:
    Sep 26, 2009
    Messages:
    8,036
    Resources:
    25
    Maps:
    3
    Spells:
    10
    Tutorials:
    3
    JASS:
    9
    Resources:
    25
    Updated to use RealEvent.

    Can another mod look over both resources?
     
  16. Bribe

    Bribe

    Joined:
    Sep 26, 2009
    Messages:
    8,036
    Resources:
    25
    Maps:
    3
    Spells:
    10
    Tutorials:
    3
    JASS:
    9
    Resources:
    25
    Updated to fix a syntactical error with the newer version: forgot a comma.

    Thank you SpellBound for finding this bug!
     
  17. edo494

    edo494

    Joined:
    Apr 16, 2012
    Messages:
    3,852
    Resources:
    5
    Spells:
    1
    JASS:
    4
    Resources:
    5
    why did you split the resource to two libraries? the only function inside RealEvent could just as much be private function at the top of the UnitIndexerGUI lib. which would also reduce library name pollution(library_once is very deadly, because if I make one myself with the same name, I may be wondering why Im getting syntax errors, because only your version is parsed)
     
  18. Bribe

    Bribe

    Joined:
    Sep 26, 2009
    Messages:
    8,036
    Resources:
    25
    Maps:
    3
    Spells:
    10
    Tutorials:
    3
    JASS:
    9
    Resources:
    25
    Updated with the recommended change!
     
  19. edo494

    edo494

    Joined:
    Apr 16, 2012
    Messages:
    3,852
    Resources:
    5
    Spells:
    1
    JASS:
    4
    Resources:
    5
    I love the On(De)IndexUnit event, its not eye sore and doesnt require a tutorial to use unlike the other one.

    I wonder tho, is the lazy initialization needed? because right now you have to evaluate both conditions every time you call the DoThings function, which could be potentially dropped down to one if you were to pre-initialize the triggers inside module or struct or whatnot + then you wouldnt need to return the trigger. I also dont really see why you reassign the trigger to itself(since the param t is returned effectively).

    If you didnt return it, you probably wouldnt need the tempTrig shenanigans either + you would save yourself an assignment inside the API calls.
     
  20. Bribe

    Bribe

    Joined:
    Sep 26, 2009
    Messages:
    8,036
    Resources:
    25
    Maps:
    3
    Spells:
    10
    Tutorials:
    3
    JASS:
    9
    Resources:
    25
    Thank you for bringing that to my attention. I've gone ahead and fixed a bug when you made me ponder my script for a bit. The function was previously going to bug in most circumstances. With that change, the event only gets created once. I suppose I could attach a boolean "IsTriggerWaitOnSleeps" instead of creating them like that, but I think this is fine.

    Edit: I've also made it so that the OnUnitIndexerInitialized trigger is destroyed the first time it's run, since it only needs to be used once.