[Solved] Unit Group in Chain Lightning

Level 5
Joined
Feb 1, 2024
Messages
44
Hello, I've simulated the animation of Chain Lightning with the following trigger:
(This is just part of the triggers, and it is not MUI but I'll add it later)


  • Chain Lightning cast
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Chain Lightning
    • Actions
      • Set CLCaster[0] = (Triggering unit)
      • Set CLTarget[0] = (Target unit of ability being cast)
      • Set CLAoE[0] = (750.00 + (100.00 x (Real((Level of (Ability being cast) for (Triggering unit))))))
      • Set CLPoint[0] = (Position of (Target unit of ability being cast))
      • Set CLPoint[1] = (Position of (Triggering unit))
      • Set CLTimer[0] = 0.00
      • Set CLTimer[1] = 10.00
      • Set CLLightningCount[0] = 0
      • Set CLDamage[0] = (10.00 + (5.00 x (Real((Level of (Ability being cast) for (Triggering unit))))))
  • ------------------------------------------------------------------------------------------------------------------
  • ------------------------------------------------------------------------------------------------------------------
    • Unit Group - Add (Triggering unit) to CLGroup[3]
    • Lightning - Create a Chain Lightning effect from source CLPoint[1] to target CLPoint[0]
    • Set CLLightning[CLLightningCount[0]] = (Last created lightning effect)
    • Unit Group - Add CLTarget[0] to CLGroup[3]
    • Custom script: call RemoveLocation(udg_CLPoint[0])
    • Custom script: call RemoveLocation(udg_CLPoint[1])
    • Trigger - Turn on Chain Lightning bounce <gen>
  • Chain Lightning bounce
    • Events
      • Time - Every 0.25 seconds of game time
    • Conditions
    • Actions
      • Set CLPoint[0] = (Position of CLTarget[CLLightningCount[0]])
      • Set CLCount = 0
      • Set CLGroup[0] = (Units within CLAoE[0] of CLPoint[0])
      • Unit Group - Pick every unit in CLGroup[0] and do (Actions)
        • Loop - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • ((Picked unit) is in CLGroup[3]) Equal to False
            • Then - Actions
              • Unit Group - Add (Picked unit) to CLGroup[2]
            • Else - Actions
      • Set CLGroup[1] = (Random 1 units from CLGroup[2])
      • Unit Group - Pick every unit in CLGroup[1] and do (Actions)
        • Loop - Actions
          • Unit Group - Add (Picked unit) to CLGroup[3]
          • Set CLCount = (CLCount + 1)
          • Set CLPoint[1] = (Position of (Picked unit))
          • Set CLLightningCount[0] = (CLLightningCount[0] + 1)
          • Set CLTarget[CLLightningCount[0]] = (Picked unit)
      • Unit Group - Remove all units of CLGroup[2] from CLGroup[2]
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • CLCount Equal to 0
        • Then - Actions
          • Trigger - Turn off (This trigger)
        • Else - Actions
          • Lightning - Create a Chain Lightning effect from source CLPoint[0] to target CLPoint[1]
          • Set CLLightning[CLLightningCount[0]] = (Last created lightning effect)
      • Custom script: call RemoveLocation(udg_CLPoint[0])
      • Custom script: call RemoveLocation(udg_CLPoint[1])
      • Custom script: call DestroyGroup(udg_CLGroup[0])
      • Custom script: call DestroyGroup(udg_CLGroup[1])

But I don't understand why if I add the following lines in between two lines of dash in the first trigger it will not add any unit into CLGroup[3] (store already hit targets so it will not bounce to them again) and it will run endlessly:

  • Set CLGroup[2] = (Units within CLAoE[0] of CLPoint[0])
  • Set CLGroup[3] = CLGroup[2]
  • Unit Group - Remove all units of CLGroup[2] from CLGroup[2]
  • Unit Group - Remove all units of CLGroup[3] from CLGroup[3]

As I think if I don't set a Unit Group it will leak, so I created 2 groups, then emptied these groups to store units.
 
Level 29
Joined
Sep 26, 2009
Messages
2,594
First of all, the following
  • Unit Group - Remove all units of CLGroup[2] from CLGroup[2]
can be replaced by a better function:
  • Unit Group - Remove all units from CLGroup[2].

The reason why your trigger runs endlessly is because of the following line:
  • Set CLGroup[3] = CLGroup[2]
Variables store references to created objects (except for base types like integers, reals, booleans, but basically everything else is a reference).
So you did this:
  • Set CLGroup[2] = (Units within CLAoE[0] of CLPoint[0])
which creates a unit group and assigns a reference to this object into variable CLGroup[2].
Then you do
  • Set CLGroup[3] = CLGroup[2]
which assign the reference of CLGroup[2] to CLGroup[3]. So at this point, both CLGroup[2] and CLGroup[3] point to same object - to same unit group.

In your 'bounce' trigger you check the following condition:
  • ((Picked unit) is in CLGroup[3]) Equal to False
but also do
  • Unit Group - Remove all units of CLGroup[2] from CLGroup[2]
Since CLGRoup[2] adn CLGroup[3] reference same unit group, you basically just clear CLGroup[3], meaning the condition will always pass, leading to endless bounces.
 
Level 5
Joined
Feb 1, 2024
Messages
44
Thanks so much!

But is there a way to create an Empty Unit Group like I can set a unit variable to No unit so it will not point to any objects at the beginning? Or is the Unit Group in an array empty by default so I just add and remove units in it?
 
Level 29
Joined
Sep 26, 2009
Messages
2,594
By default, a unit group variable has an empty unit group assigned to it. You can see it even in the variable's configuration: For variable of type "unit group" its initial value says "Empty Unit Group (Default)".
For unit group array variables, the number of pre-created unit groups matches the number in "Size" option.
So if I create a unit group array variable called "MyGroups" and set it with Size: 3, then the pre-created unit groups will be in:
  • MyGroups[1]
  • MyGroups[2]
  • MyGroups[3]

There is no GUI action to create a new unit group, however you can use custom script to do that:
  • Custom script: set udg_<variable_name> = CreateGroup()
Any variable created in GUI trigger editor must be prefixed with "udg_" in custom script. Let's say I want to create a new unit group and assign it to MyGroups array variable under index 8, I would use the following custom script:
  • Custom script: set udg_MyGroups[8] = CreateGroup()
 
Top