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.

[JASS] Filtering and UnitGroup Help PLEASE

Discussion in 'Triggers & Scripts' started by Darkwing, Sep 13, 2011.

  1. Darkwing

    Darkwing

    Joined:
    May 15, 2008
    Messages:
    150
    Resources:
    1
    Maps:
    1
    Resources:
    1
    OK, I'm doing some systems for wave-like spells and I need these things cleared up.

    Q1 - After trying various ways to save a unit group to a hashtable I found out eventualy that

    Code (vJASS):
    call SaveGroupHandle(Hashtable, Pkey, Ckey, ExampleGroup)


    does not work under any circumstances. Or maybe the LoadGroupHashtable doesn't work but I cannot really know which one is if I cannot load the saved content. Problem is that it's (I guess) inefficient to make a timer for each unit affected by spell and then run it than to cycle through one group using one timer. I thought of a way to work around this but it's somewhat complex than just saving so I would like to know if this functions can be get to work??

    Q2 - I need the filtering thingie cleared up, and I cannot seem to find a proper tutorial/thread about that case, under the filtering I mean a functions that filters if a unit is enemy, if it's alive and organic.
    The main problem I have here is the thing with Condition1 And Condition2 thing, can I make something with more than 2 "and"s in the same line but with using parenthesis to make it in for of Cond1 and Cond2 (Cond1 and (Cond2 and Cond3)) instead of Cond1 and Cond2 and Cond3?? Also do I write and with small or capital "A"?

    Thanks in advance :thumbs_up:
     
  2. Bannar

    Bannar

    Joined:
    Mar 19, 2008
    Messages:
    3,087
    Resources:
    20
    Spells:
    5
    Tutorials:
    1
    JASS:
    14
    Resources:
    20
    #2.
    Code (vJASS):
    local unit u = unitTocheck
    local player p = playerToCheck
    if IsUnitEnemy(unitTocheck, playerToCheck) and (GetWidgetLife(unitTocheck) > 0.405) and not IsUnitType(unitTocheck, UNIT_TYPE_STRUCTURE) and not IsUnitType(unitTocheck, UNIT_TYPE_MECHANICAL) then
        // stuff
    endif
    set u = null
    set p = null

    Native IsUnitEnemy checks is unit 'unitTocheck' in an enemy to player 'playerTocheck'. Rest you probably understand.

    #1 Post whole script?
    Meaby global group usage can help you.
     
  3. Maker

    Maker

    Joined:
    Mar 6, 2006
    Messages:
    9,181
    Resources:
    17
    Maps:
    2
    Spells:
    14
    Tutorials:
    1
    Resources:
    17
    1. It does ork. Maybe you're using wrong parent- or child key, destroying the group prematurely or not initializing the hashtable.
     
  4. Darkwing

    Darkwing

    Joined:
    May 15, 2008
    Messages:
    150
    Resources:
    1
    Maps:
    1
    Resources:
    1
    About Q1 here is the script, I used to try to save the unit groups to hashtable in GUI for wave type spells so I can store already damaged units, but I couldn;t get it to work there also.

    Here is the test script where I've tried to see if the func work, it has nothing to do with ability:

    Code
    Code (vJASS):
    function TestGroupHashtable takes nothing returns nothing
        local group g = GetUnitsInRectAll(gg_rct_Region_000)
        local group g2
        local unit u
        call SaveGroupHandle(udg_Hashtable, 1, 1, g)
        loop
            set u = FirstOfGroup(g)
            exitwhen u == null
            call BJDebugMsg(GetUnitName(u))
            call GroupRemoveUnit(g, u)
        endloop
        call GroupClear(g)
        call TriggerSleepAction(5.00)
        set g2 = LoadGroupHandle(udg_Hashtable, 1, 1)
        call BJDebugMsg("loaded group units:")
        loop
            set u = FirstOfGroup(g2)
            exitwhen u == null
            call BJDebugMsg(GetUnitName(u))
            call GroupRemoveUnit(g2, u)
        endloop
    endfunction

    //=======================

    function InitTrig_Test takes nothing returns nothing
        local trigger T = CreateTrigger()
        call TriggerRegisterPlayerChatEvent(T, Player(0), "-test", true)
        call TriggerAddAction(T, function TestGroupHashtable)
        set T = null
    endfunction


    I didn't removed leaks no need to point me to that this is just for testing, in the Region I have 5 units and first loop show all of their names, the Hashtable is initialized, I'm using the same for some other systems and spells and they all work.
    Where do I do it wrong?

    Thanks for the help. :thumbs_up:

    :fp: EDIT: Oh yeah Spinnaker thanks for the filtering code you rulez ^^ :thumbs_up:
     
  5. Ceday

    Ceday

    Joined:
    Feb 22, 2010
    Messages:
    1,098
    Resources:
    0
    Resources:
    0
    1-In first loop you are removing every unit one by one from group, when loop ends the group is empty.

    2-After first loop, next line you are clearing an empty group, which does nothing.

    3-
    Code (vJASS):
    //You are loading an empty group now.
    set g2 = LoadGroupHandle(udg_Hashtable, 1, 1)
     
  6. Bannar

    Bannar

    Joined:
    Mar 19, 2008
    Messages:
    3,087
    Resources:
    20
    Spells:
    5
    Tutorials:
    1
    JASS:
    14
    Resources:
    20
    Code (vJASS):
    // Instead of:
        call SaveGroupHandle(udg_Hashtable, 1, 1, g)
    // Use
        call SaveGroupHandle(udg_Hashtable, 1, 1, GetUnitsInRectAll(gg_rct_Region_000))

    As mentioned, you're clearing the group, thus saved group will be empty.
     
  7. Darkwing

    Darkwing

    Joined:
    May 15, 2008
    Messages:
    150
    Resources:
    1
    Maps:
    1
    Resources:
    1
    OK I've overnoticed that thingie with clear group function my bad.

    But wtf that sucks if I saved GroupHandle into hashtable shouldn't that info remain there even if I change the group g because it's uhm "saved"? That works with unit you set a unit save it and you can change that.

    I mean my point of view is like this, having a wave spell which goes and has dunno 200 AoE for example, if I move it 50, by 50 distance the units in the starting point will remain there roughly 4 times, and if I damage every time when the moving is done ('cuz of the new units), I'll deal 4 time dmg to picked ones. I want to damage a unit then add it to a group and than save that group into a hastable, so I can load it on the next damage and check if the picked unit is already damaged. I could do that with a global group, but what if I have two of the same waves going after each other or crossroading, only one wave would deal dmg??
     
  8. Bannar

    Bannar

    Joined:
    Mar 19, 2008
    Messages:
    3,087
    Resources:
    20
    Spells:
    5
    Tutorials:
    1
    JASS:
    14
    Resources:
    20
    To make is clear: SaveGroupHandle runs as last action, so any actions that apply immidiately to given group will have impact on value saved.
    You can still stick with hashtable method.
     
  9. Darkwing

    Darkwing

    Joined:
    May 15, 2008
    Messages:
    150
    Resources:
    1
    Maps:
    1
    Resources:
    1
    So no need to clear the group? I mean I clear it on the end of the wave spell along with destroying?

    Or I do it at the end of function or combine it with a small wait??

    EDIT: Uhm I've removed the removing of units in the loop but if I remove that, the loop goes infinite since there will be no exitwhen u == null since no units are removed.

    Also I don't get it what you think under "you can still stick with hashtable method", SaveGroupHandle is Hashtable metod it saves the group into hashtable. :vw_wtf:
     
  10. Bannar

    Bannar

    Joined:
    Mar 19, 2008
    Messages:
    3,087
    Resources:
    20
    Spells:
    5
    Tutorials:
    1
    JASS:
    14
    Resources:
    20
    You saw my script above?
    Just make sure you save untouched group. If you want to add units into this group you can either:
    Code (vJASS):
    set g2 = LoadGroupHandle(udg_Hashtable, 1, 1)
    call GroupAddUnit(g2, someunit)

    // Or
    call GroupAddUnit(LoadGroupHandle(udg_Hashtable, 1, 1), someunit)
    set g2 = LoadGroupHandle(udg_Hashtable, 1, 1)

    It's best to save empty group into hashtable and just add units with time (wave moves further):
    Code (vJASS):
    call SaveGroupHandle(udg_Hashtable, 1, 1, CreateGroup())

    Now whenever you want to add units just set saved group to local (to omit spamming LoadGroupHandle()), and add those.
     
    Last edited: Sep 14, 2011
  11. Darkwing

    Darkwing

    Joined:
    May 15, 2008
    Messages:
    150
    Resources:
    1
    Maps:
    1
    Resources:
    1
    OK I got it now will try that immediatly, sorry for misunderstanding, thanks for the help man :thumbs_up:
     
  12. Maker

    Maker

    Joined:
    Mar 6, 2006
    Messages:
    9,181
    Resources:
    17
    Maps:
    2
    Spells:
    14
    Tutorials:
    1
    Resources:
    17
    Spinnaker, you don't have to save the handle if you're manipulating a group loaded from a hashtable. The handle is already saved. Saving a group handle into a hashtable does not save the contents of the group. It saves the handle, so you know which group it is.
     
  13. Darkwing

    Darkwing

    Joined:
    May 15, 2008
    Messages:
    150
    Resources:
    1
    Maps:
    1
    Resources:
    1
    So what's the way to save the content of a group if not this one?
    Isn't a group a content of units?
    How does that work for a single unit than, I mean if saving it to hashtable means saving it's handle..., uhm I'm too confused now :vw_wtf:

    Don't getting this also if I dont clear up and destroy the group and null the variable, wouldn't it leak on each execution of Exe Function?

    I'm currently doing the code, will check if it works if not I'll post it here in hope of solving the issue.

    Thanks Maker :thumbs_up:


    EDIT: OK here is the code, but now I can't get the wave dummy unit to move, I really don't know what's the problem, I did yesterday a code like this just without damage and it worked??
    Thanks in advance for help.

    Code (vJASS):
    [HIDDEN="Code"]
    //==========//
    // WAVE     //
    //==========//

    function Wave_Exe takes nothing returns nothing
        local timer t = GetExpiredTimer()
        local integer id = GetHandleId(t)
        local integer counter = LoadInteger(udg_Hashtable, id, 1)
        local real angle = LoadReal(udg_Hashtable, id, 2)
        local real damage = LoadReal(udg_Hashtable, id, 3)
        local unit Wave = LoadUnitHandle(udg_Hashtable, id, 4)
        local group Damaged = LoadGroupHandle(udg_Hashtable, id, 5)
        local location p = GetUnitLoc(Wave)
        local group g = GetUnitsInRangeOfLocAll(200.0, p)
        local unit u
        call BJDebugMsg("Runned")
        if counter <= 11 then
            call SaveInteger(udg_Hashtable, id, 1, counter+1)
            call SetUnitX(Wave, PolarProjectionX(GetUnitX(Wave), 50, angle))
            call SetUnitY(Wave, PolarProjectionY(GetUnitY(Wave), 50, angle))
            loop
                exitwhen u == null
                set u = FirstOfGroup(g)
                if IsUnitInGroup(u, Damaged) == false then
                    call UnitDamageTarget(Wave, u, damage, true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_NORMAL, WEAPON_TYPE_WHOKNOWS)
                    call DestroyEffect(AddSpecialEffectTarget("Mana Wave.mdx", u, "chest"))
                    call GroupAddUnit(Damaged, u)
                    call SaveGroupHandle(udg_Hashtable, id, 5, Damaged)
                endif
                call GroupRemoveUnit(g, u)
            endloop
        else
            call PauseTimer(t)
            call DestroyTimer(t)
            call FlushChildHashtable(udg_Hashtable, id)
            call KillUnit(Wave)
        endif
        call DestroyGroup(g)
        call DestroyGroup(Damaged)
        call RemoveLocation(p)
        set u = null
        set Wave = null
        set g = null
        set Damaged = null
        set p = null
        set t = null      
    endfunction

    function Wave_Start takes nothing returns nothing
        local timer t = CreateTimer()
        local integer id = GetHandleId(t)
        local integer counter = 0
        local real angle = GetUnitFacing(GetTriggerUnit())
        local location p = GetUnitLoc(GetTriggerUnit())
        if GetSpellAbilityId() == 'A00L' then
            set bj_lastCreatedUnit = CreateUnitAtLoc(GetOwningPlayer(GetTriggerUnit()), 'h008', p, GetUnitFacing(GetTriggerUnit()))
            call SaveUnitHandle(udg_Hashtable, id, 4, bj_lastCreatedUnit)    
            call SaveInteger(udg_Hashtable, id, 1, counter)
            call SaveReal(udg_Hashtable, id, 2, angle)
            call SaveReal(udg_Hashtable, id, 3, 100.0)
            call SaveGroupHandle(udg_Hashtable, id, 5, CreateGroup())
            call TimerStart(t, 0.4, true, function Wave_Exe)
            set t = null
        endif
        call RemoveLocation(p)
        set p = null
    endfunction

    //===================================

    function InitTrig_Wave_Test takes nothing returns nothing
        local trigger T = CreateTrigger()
        call TriggerRegisterAnyUnitEventBJ(T, EVENT_PLAYER_UNIT_SPELL_EFFECT)
        call TriggerAddAction(T, function Wave_Start)
        set T = null
    endfunction[/HIDDEN]
     
    Last edited: Sep 14, 2011
  14. Maker

    Maker

    Joined:
    Mar 6, 2006
    Messages:
    9,181
    Resources:
    17
    Maps:
    2
    Spells:
    14
    Tutorials:
    1
    Resources:
    17
    The group object holds the information of what units are in it. The handle is a pointer to the group object.
     
  15. Darkwing

    Darkwing

    Joined:
    May 15, 2008
    Messages:
    150
    Resources:
    1
    Maps:
    1
    Resources:
    1
    Maker can u explain me how does the code with the upper mentioned hashtable save/load works for units then, I mean unit is handle?

    Ive tested this short code and it shows two time the name of the unit even when I nulled the variable.

    code
    Code (vJASS):
    function Test takes nothing returns nothing
        local unit u = gg_unit_Hblm_0038
        call SaveUnitHandle(udg_Hashtable, 1, 1, u)
        call BJDebugMsg(GetUnitName(u))
        set u = null
        call TriggerSleepAction(5.00)
        set u = LoadUnitHandle(udg_Hashtable, 1, 1)
        call BJDebugMsg(GetUnitName(u))
    endfunction

    //==================

    function InitTrig_Opaa_Z takes nothing returns nothing
        local trigger T = CreateTrigger()
        call TriggerRegisterPlayerChatEvent(T, Player(0), "-opa", true)
        call TriggerAddAction(T, function Test)
        set T=null
    endfunction


    Any help with the upper code, I still haven't figured it out?
     
  16. Bannar

    Bannar

    Joined:
    Mar 19, 2008
    Messages:
    3,087
    Resources:
    20
    Spells:
    5
    Tutorials:
    1
    JASS:
    14
    Resources:
    20
    Yeah you have nulled it and set again to loadunithandle value. In this case unit 'u' has been set to unit stored into hashtable, thus it's name will be displayed.
    You have to execute RemoveUnit(u) to make sure it's same won't be displayed.
    Saving any value in hashtable doesn't create additional object, it's just a reference to existing one. This reference is pointing at given object, and if somehow the pointed value gets removed the savedvalue will store nothing usefull.

    ClearingGroup/Removing units from it works in similar way, yet still you can display savedgroup id since group exists, but it's empty. Unless you destroy it, the group's id can be shown. Destroying group in this case can be compared to displaying removed unit's name.