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. Don’t forget to sign up for the Hive Cup. There’s a 555 EUR prize pool. Sign up now!
    Dismiss Notice
  4. The Hive Workshop Cup contest results have been announced! See the maps that'll be featured in the Hive Workshop Cup tournament!
    Dismiss Notice
  5. The results are out! Check them out.
    Dismiss Notice
  6. The poll for Hive's 12th Concept Art Contest is up! Go cast your vote for your favourite genie!
    Dismiss Notice
  7. The raddest synthwave tracks were chosen - Check out our Music Contest #12 - Results and congratulate the winners!
    Dismiss Notice
  8. 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.

Why does this trigger ignore the invulnerable effect sometimes?

Discussion in 'Triggers & Scripts' started by Dinodin, Jul 11, 2014.

  1. Dinodin

    Dinodin

    Joined:
    Jul 19, 2007
    Messages:
    492
    Resources:
    2
    Maps:
    2
    Resources:
    2
    +SOLVED+

    I got a problem with one of my triggered spells and can't see why it crashes sometimes. It's meant to give the casting Hero and all other friendly Heroes in the map an invulnerability for a short period of time after the Hero has casted the spell sometimes it gives the invulnerability like it should and sometimes it ignores it, why does it happening?

    The triggers of the spell.
    • Divine Light Cast
      • Events
        • Unit - A unit Finishes casting an ability
      • Conditions
        • (Ability being cast) Equal to Divine Light
      • Actions
        • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
          • If - Conditions
            • DivineLightIndex Equal to 0
          • Then - Actions
            • Trigger - Turn on Divine Light Loop <gen>
          • Else - Actions
        • Custom script: set bj_wantDestroyGroup = true
        • Unit Group - Pick every unit in (Units in (Playable map area)) and do (Actions)
          • Loop - Actions
            • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
              • If - Conditions
                • ((Picked unit) is A Hero) Equal to True
                • ((Picked unit) belongs to an ally of (Triggering player)) Equal to True
              • Then - Actions
                • Set DivineLightIndex = (DivineLightIndex + 1)
                • Set DivineLightUnit[DivineLightIndex] = (Picked unit)
                • Set DivineLightDur[DivineLightIndex] = (0.00 + (2.00 x (Real((Level of Divine Light for (Triggering unit))))))
                • Unit - Add Invulnerable (Divine Light) to DivineLightUnit[DivineLightIndex]
              • Else - Actions

    • Divine Light Loop
      • Events
        • Time - Every 0.25 seconds of game time
      • Conditions
      • Actions
        • For each (Integer DivineLightLoop) from 1 to DivineLightIndex, do (Actions)
          • Loop - Actions
            • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
              • If - Conditions
                • DivineLightDur[DivineLightLoop] Less than or equal to 0.00
              • Then - Actions
                • Unit - Remove Invulnerable (Divine Light) from DivineLightUnit[DivineLightLoop]
                • Set DivineLightDur[DivineLightLoop] = DivineLightDur[DivineLightIndex]
                • Set DivineLightUnit[DivineLightLoop] = DivineLightUnit[DivineLightIndex]
                • Set DivineLightIndex = (DivineLightIndex - 1)
                • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                  • If - Conditions
                    • DivineLightIndex Equal to 0
                  • Then - Actions
                    • Trigger - Turn off (This trigger)
                  • Else - Actions
              • Else - Actions
                • Set DivineLightDur[DivineLightLoop] = (DivineLightDur[DivineLightLoop] - 0.25)
     
    Last edited: Aug 21, 2014
  2. Bannar

    Bannar

    Joined:
    Mar 19, 2008
    Messages:
    3,087
    Resources:
    20
    Spells:
    5
    Tutorials:
    1
    JASS:
    14
    Resources:
    20
    This is some bad indexing design.

    Let's assume you caught 100 units and made them invurneable. DivineLightIndex would be set to 100.
    Now, when a unit gets removed from loop the trigger, the so mentioned DivineLightIndex will be decreased. E.g removal of first unit (DivineLightUnit[] with index 1) from the loop would effectively reduce iteration size to 99. That doesn't mean that unit DivineLightUnit[100] has been already removed, thus reference to such unit is lost (or rather its just omited, since it's still being stored in global array).

    Fix your indexing method or use Bribe's UnitIndexer for GUI.
     
  3. Dinodin

    Dinodin

    Joined:
    Jul 19, 2007
    Messages:
    492
    Resources:
    2
    Maps:
    2
    Resources:
    2
    Well I didn't create this trigger, someone else helped me but I don't remember that user so he can't help me fix it and I'm kinda noobish at triggering..
     
  4. Gismo359

    Gismo359

    Joined:
    Jul 14, 2011
    Messages:
    771
    Resources:
    44
    Packs:
    4
    Maps:
    40
    Resources:
    44
    Well, unit variables dont cause leaks, afaik. Or is there some other reason it should be done in another way?

    Also, when you reduce DivineLightIndex, you should reduce DivineLightLoop, too.

    EDIT: Cant you just use a dummy unit with a spell based of Big Bad Voodoo, and add an expiration timer to him?
     
  5. Dinodin

    Dinodin

    Joined:
    Jul 19, 2007
    Messages:
    492
    Resources:
    2
    Maps:
    2
    Resources:
    2
    lol that sounds abit to complicated and i'm not sure that will be very effective.. there should be some way to fix the trigger of it instead because 50% of the times it works like it should and 50% of the times it doesn't..
     
  6. McQvaBlood

    McQvaBlood

    Joined:
    Jul 3, 2010
    Messages:
    536
    Resources:
    44
    Packs:
    4
    Maps:
    40
    Resources:
    44
    I have provided the simplest solution I could think of. It will completely replace these, by the way, non-MUI and terribly scripted triggers.
    I have also added detailed description of what each of these three triggers do so you can understand what you're doing, instead of adopting random triggers.

    (1) Cast Trigger
    • DivLight Cast
      • Events
        • Unit - A unit Starts the effect of an ability
      • Conditions
        • (Ability being cast) Equal to Divine Light
      • Actions
        • Set TempInteger = 0
        • For each (Integer A) from 1 to 10, do (Actions)
          • Loop - Actions
            • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
              • If - Conditions
                • TempInteger Equal to 0
                • (Number of units in Divine_Light_GROUP[(Integer A)]) Equal to 0
              • Then - Actions
                • Set TempInteger = (Integer A)
              • Else - Actions
        • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
          • If - Conditions
            • TempInteger Not equal to 0
          • Then - Actions
            • Set Divine_Light_GROUP[TempInteger] = (Units in (Playable map area) matching ((((Matching unit) belongs to an ally of (Owner of (Casting unit))) Equal to True) and (((Matching unit) is A Hero) Equal to True)))
            • Unit Group - Pick every unit in Divine_Light_GROUP[TempInteger] and do (Actions)
              • Loop - Actions
                • Unit - Make (Picked unit) Invulnerable
            • Countdown Timer - Start Divine_Light_TIMER[TempInteger] as a One-shot timer that will expire in (0.00 + (2.00 x (Real((Level of Divine Light for (Casting unit)))))) seconds
          • Else - Actions

    • The first part is a very basic GUI indexing system. We set TempInteger, a global integer, to 0. Then we iterate with A from 0 to 10. If we find a Divine_Light_GROUP, a global unit group, that is empty, we set TempInteger to whatever index that has, say 3. This in turn stops the loop because we loop only while TempInteger is 0.
    • To ensure we don't run out of indexes we check if TempInteger is really not 0.
    • We add all heroes on the map to our DivineLight_GROUP[TempInteger] and run a DivineLight_TIMER, a global timer.
    (2) Expire Trigger
    • DivLight Timer
      • Events
      • Conditions
      • Actions
        • For each (Integer A) from 1 to 10, do (Actions)
          • Loop - Actions
            • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
              • If - Conditions
                • (Remaining time for Divine_Light_TIMER[(Integer A)]) Equal to 0.00
                • (Number of units in Divine_Light_GROUP[(Integer A)]) Not equal to 0
              • Then - Actions
                • Unit Group - Pick every unit in Divine_Light_GROUP[(Integer A)] and do (Actions)
                  • Loop - Actions
                    • Set TempBoo = True
                    • For each (Integer B) from 1 to 10, do (Actions)
                      • Loop - Actions
                        • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                          • If - Conditions
                            • (Integer A) Not equal to (Integer B)
                            • ((Picked unit) is in Divine_Light_GROUP[(Integer B)]) Equal to True
                          • Then - Actions
                            • Set TempBoo = False
                          • Else - Actions
                    • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                      • If - Conditions
                        • TempBoo Equal to True
                      • Then - Actions
                        • Unit - Make (Picked unit) Vulnerable
                      • Else - Actions
                • Custom script: call DestroyGroup(udg_Divine_Light_GROUP[GetForLoopIndexA()])
              • Else - Actions
    • You may notice that I declared no event. The event is that any of my 10 Divine_Light_TIMERS expire. However, I'm lazy enough to do this instead. Adding them one by one also works, but this is much faster when you need 100 timers for example.
      (3) Lazy
      • DivLight I
        • Events
          • Map initialization
        • Conditions
        • Actions
          • For each (Integer A) from 1 to 10, do (Actions)
            • Loop - Actions
              • Trigger - Add to DivLight Timer <gen> the event (Time - Divine_Light_TIMER[(Integer A)] expires)
    • I check to see if any of my Divine_Light_GROUPs are not empty while their timer expired, which would signal that it is time for them to turn vulnerable again.
    • However, I run a Loop with B to see if they are in another group making them invulnerable, as this would require them to stay invulnerable.
    • I null the group I loaded them into after turning them back vulnerable.
     
  7. Dinodin

    Dinodin

    Joined:
    Jul 19, 2007
    Messages:
    492
    Resources:
    2
    Maps:
    2
    Resources:
    2
    Oh that's a much more complicated triggers..but if it makes the ability work like it should then it's good. Btw I have an Invulnerable-ability for the spell, can I just replace the "Make (Picked Unit) Invulnerable" to "Add Invulnerable (Divine Light) to (Picked Unit)"?? Could also maybe post a map with the triggers so I can simply copy and paste them into my map?
     
  8. McQvaBlood

    McQvaBlood

    Joined:
    Jul 3, 2010
    Messages:
    536
    Resources:
    44
    Packs:
    4
    Maps:
    40
    Resources:
    44
    Yes, you can just replace it with an ability add line. I already did this in the map I'm posting for you.

    I didn't feel like creating any abilities in the object editor, so I'm currently using Animate Dead as the base spell and Evasion as the spell that it gives.

    You can very quickly change it to whatever you want. I added two more lines to Divine Light INIT.
    INIT
    • Divine Light INIT
      • Events
        • Map initialization
      • Conditions
      • Actions
        • Set zz_DivLight_SPELL = Animate Dead
        • Set zz_DivLight_SPELL_DUMMY = Evasion (Neutral Hostile)
        • For each (Integer A) from 1 to 10, do (Actions)
          • Loop - Actions
            • Trigger - Add to Divine Light DONE <gen> the event (Time - Divine_Light_TIMER[(Integer A)] expires)
    Simply replace these values:
    • zz_DivLight_SPELL should point to the ability the hero casts.
    • zz_DivLight_SPELL_DUMMY should point to the ability that you made to make the heroes invulnerable.

    EDIT
    If you want to perhaps change how long the spell lasts, you can change the very last line of Divine Light cast.
    • Countdown Timer - Start Divine_Light_TIMER[TempInteger] as a One-shot timer that will expire in (0.00 + (2.00 x (Real((Level of zz_DivLight_SPELL for (Casting unit)))))) seconds
    It currently lasts 2/4/6 seconds. If you wanted it to last 5/8/11 seconds instead, it would look like this:
    • Countdown Timer - Start Divine_Light_TIMER[TempInteger] as a One-shot timer that will expire in (2.00 + (3.00 x (Real((Level of zz_DivLight_SPELL for (Casting unit)))))) seconds
     

    Attached Files:

  9. Dat-C3

    Dat-C3

    Joined:
    Mar 15, 2012
    Messages:
    2,470
    Resources:
    10
    Models:
    1
    Maps:
    5
    Spells:
    3
    Tutorials:
    1
    Resources:
    10
    Actually unit variables do indeed cause leaks, GUI'ers need to learn to set their unit variables to no unit.
     
  10. Dinodin

    Dinodin

    Joined:
    Jul 19, 2007
    Messages:
    492
    Resources:
    2
    Maps:
    2
    Resources:
    2
    Oh thank so much for the help! The spell works like it should now and I hope it will not cause any more bugs.