• Listen to a special audio message from Bill Roper to the Hive Workshop community (Bill is a former Vice President of Blizzard Entertainment, Producer, Designer, Musician, Voice Actor) 🔗Click here to hear his message!
  • Read Evilhog's interview with Gregory Alper, the original composer of the music for WarCraft: Orcs & Humans 🔗Click here to read the full interview.

[General] Number of N units Memory Leak

Level 6
Joined
May 13, 2023
Messages
72
Hello again Hive, i have a simple spell that uses Pick random N number of units action and when I try to use bj_wantDestroyGroup to avoid memory leak the spell stops working, is there any solution to this, i need the N number of units for my spell.
Heres the trigger
  • Epicedium
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Epicedium
    • Actions
      • Set VariableSet EpicediumCaster = (Triggering unit)
      • Set VariableSet EpicediumGroup = (Units within 500.00 of (Position of EpicediumCaster) matching ((((Matching unit) is A structure) Equal to False) and (((Matching unit) belongs to an enemy of (Owner of EpicediumCaster).) Equal to True)).)
      • Set VariableSet EpicediumCount = (Number of units in EpicediumGroup)
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Level of Epicedium for EpicediumCaster) Equal to 1
        • Then - Actions
          • Custom script: set bj_wantDestroyGroup = true
          • Unit Group - Pick every unit in (Random 6 units from EpicediumGroup) and do (Actions)
            • Loop - Actions
              • Unit - Create 1 Dummy (Nothing) for (Owner of EpicediumCaster) at (Position of EpicediumCaster) facing Default building facing degrees
              • Unit - Turn collision for (Last created unit) Off.
              • Unit - Add Epicedium (Dummy) to (Last created unit)
              • Unit - Set level of Epicedium (Dummy) for (Last created unit) to (Level of Epicedium for EpicediumCaster)
              • Unit - Order (Last created unit) to Orc Far Seer - Chain Lightning (Picked unit)
              • Unit - Add a 1.00 second Generic expiration timer to (Last created unit)
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • EpicediumCount Less than or equal to 6
            • Then - Actions
              • Unit - Set life of EpicediumCaster to ((25.00 x (Real(EpicediumCount))) + (Life of EpicediumCaster))
            • Else - Actions
              • Unit - Set life of EpicediumCaster to ((25.00 x 6.00) + (Life of EpicediumCaster))
        • Else - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (Level of Epicedium for EpicediumCaster) Equal to 2
            • Then - Actions
              • Custom script: set bj_wantDestroyGroup = true
              • Unit Group - Pick every unit in (Random 8 units from EpicediumGroup) and do (Actions)
                • Loop - Actions
                  • Unit - Create 1 Dummy (Nothing) for (Owner of EpicediumCaster) at (Position of EpicediumCaster) facing Default building facing degrees
                  • Unit - Turn collision for (Last created unit) Off.
                  • Unit - Add Epicedium (Dummy) to (Last created unit)
                  • Unit - Set level of Epicedium (Dummy) for (Last created unit) to (Level of Epicedium for EpicediumCaster)
                  • Unit - Order (Last created unit) to Orc Far Seer - Chain Lightning (Picked unit)
                  • Unit - Add a 1.00 second Generic expiration timer to (Last created unit)
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • EpicediumCount Less than or equal to 8
                • Then - Actions
                  • Unit - Set life of EpicediumCaster to ((37.50 x (Real(EpicediumCount))) + (Life of EpicediumCaster))
                • Else - Actions
                  • Unit - Set life of EpicediumCaster to ((37.50 x 8.00) + (Life of EpicediumCaster))
            • Else - Actions
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • (Level of Epicedium for EpicediumCaster) Equal to 3
                • Then - Actions
                  • Custom script: set bj_wantDestroyGroup = true
                  • Unit Group - Pick every unit in (Random 10 units from EpicediumGroup) and do (Actions)
                    • Loop - Actions
                      • Unit - Create 1 Dummy (Nothing) for (Owner of EpicediumCaster) at (Position of EpicediumCaster) facing Default building facing degrees
                      • Unit - Turn collision for (Last created unit) Off.
                      • Unit - Add Epicedium (Dummy) to (Last created unit)
                      • Unit - Set level of Epicedium (Dummy) for (Last created unit) to (Level of Epicedium for EpicediumCaster)
                      • Unit - Order (Last created unit) to Orc Far Seer - Chain Lightning (Picked unit)
                      • Unit - Add a 1.00 second Generic expiration timer to (Last created unit)
                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    • If - Conditions
                      • EpicediumCount Less than or equal to 10
                    • Then - Actions
                      • Unit - Set life of EpicediumCaster to ((50.00 x (Real(EpicediumCount))) + (Life of EpicediumCaster))
                    • Else - Actions
                      • Unit - Set life of EpicediumCaster to ((50.00 x 10.00) + (Life of EpicediumCaster))
                • Else - Actions
      • Custom script: call DestroyGroup(udg_EpicediumGroup)
 
Level 29
Joined
Sep 26, 2009
Messages
2,596
The bj_wantDestroyGroup quite unexpectedly destroys EpicediumGroup rather than the "(random 6 units)" group:
  • before calling the actual Pick every unit action (ForGroupBJ function) which uses the bj_wantDestroyGroup, you create the unit group consisting of 6 random units
  • to create the random group, you call Doc - GetRandomSubGroup
  • that function counts units in EpicediumGroup using Doc - CountUnitsInGroup
  • however CountUnitsInGroup also uses bj_wantDestroyGroup and if it is true, it destroys the source group (EpicediumGroup)
  • after counting is done and you are back in GetRandomSubGroup function, this function then runs internally a ForGroup on EpicediumGroup to get random units
  • however at this point EpicediumGroup has already been destroyed by CountUnitsInGroup, so the trigger no longer works as expected

The solution is to just store the random unit group in a variable and after Pick Every Unit action just destroy the group using custom script
 
Top