• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

[Trigger] Revolving Unit Spawner is leaking

Status
Not open for further replies.
Level 1
Joined
Apr 20, 2019
Messages
2
Hey, I started to poke around with Worldedit few weeks ago and wanted to create "revolving" creep spawns. I can't come up with any better name for it.
So I created 6 regions where creeps spawn in next region after I kill them with condition that creeps in next spawn are dead. All good. Problem is that i can't remove leaks as I can't destroy Unit Group variable - it is condition in next cycle.

I tried whatever I could think of or find, but I lack vision. Please help to come up with technique to make this elegant and remove leaks.

  • BanditCreepInit
    • Events
      • Map initialization
    • Conditions
    • Actions
      • Set creepRegions[1] = secretCreep1 <gen>
      • Set creepRegions[2] = secretCreep2 <gen>
      • Set creepRegions[3] = secretCreep3 <gen>
      • Set creepRegions[4] = secretCreep4 <gen>
      • Set creepRegions[5] = secretCreep5 <gen>
      • Set creepRegions[6] = secretCreep6 <gen>
      • Set testCreep[1] = (Units in creepRegions[1])
      • Set testCreep[2] = (Units in creepRegions[2])
      • Set testCreep[3] = (Units in creepRegions[3])
      • Set testCreep[4] = (Units in creepRegions[4])
      • Set testCreep[5] = (Units in creepRegions[5])
      • Set testCreep[6] = (Units in creepRegions[6])
      • Set SecretCreepPoints[1] = (Center of secretCreep1 <gen>)
      • Set SecretCreepPoints[2] = (Center of secretCreep2 <gen>)
      • Set SecretCreepPoints[3] = (Center of secretCreep3 <gen>)
      • Set SecretCreepPoints[4] = (Center of secretCreep4 <gen>)
      • Set SecretCreepPoints[5] = (Center of secretCreep5 <gen>)
      • Set SecretCreepPoints[6] = (Center of secretCreep6 <gen>)
  • BanditCreepSpawn
    • Events
      • Unit - A unit Dies
    • Conditions
      • (Unit-type of (Triggering unit)) Equal to Bandit (secret creep)
    • Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (All units of testCreep[1] are dead) Equal to True
          • (All units of testCreep[2] are dead) Equal to True
          • ((Triggering unit) is in testCreep[1]) Equal to True
        • Then - Actions
          • Unit - Create 6 Bandit (secret creep) for Neutral Hostile at SecretCreepPoints[2] facing Default building facing degrees
          • Set testCreep[2] = (Last created unit group)
        • Else - Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (All units of testCreep[2] are dead) Equal to True
          • (All units of testCreep[3] are dead) Equal to True
          • ((Triggering unit) is in testCreep[2]) Equal to True
        • Then - Actions
          • Unit - Create 6 (Unit-type of (Triggering unit)) for Neutral Hostile at SecretCreepPoints[3] facing Default building facing degrees
          • Set testCreep[3] = (Last created unit group)
        • Else - Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (All units of testCreep[3] are dead) Equal to True
          • (All units of testCreep[4] are dead) Equal to True
          • ((Triggering unit) is in testCreep[3]) Equal to True
        • Then - Actions
          • Unit - Create 6 (Unit-type of (Triggering unit)) for Neutral Hostile at SecretCreepPoints[4] facing Default building facing degrees
          • Set testCreep[4] = (Last created unit group)
        • Else - Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (All units of testCreep[4] are dead) Equal to True
          • (All units of testCreep[5] are dead) Equal to True
          • ((Triggering unit) is in testCreep[4]) Equal to True
        • Then - Actions
          • Unit - Create 6 (Unit-type of (Triggering unit)) for Neutral Hostile at SecretCreepPoints[5] facing Default building facing degrees
          • Set testCreep[5] = (Last created unit group)
        • Else - Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (All units of testCreep[5] are dead) Equal to True
          • (All units of testCreep[6] are dead) Equal to True
          • ((Triggering unit) is in testCreep[5]) Equal to True
        • Then - Actions
          • Unit - Create 6 (Unit-type of (Triggering unit)) for Neutral Hostile at SecretCreepPoints[6] facing Default building facing degrees
          • Set testCreep[6] = (Last created unit group)
        • Else - Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (All units of testCreep[6] are dead) Equal to True
          • (All units of testCreep[1] are dead) Equal to True
          • ((Triggering unit) is in testCreep[6]) Equal to True
        • Then - Actions
          • Unit - Create 6 (Unit-type of (Triggering unit)) for Neutral Hostile at SecretCreepPoints[1] facing Default building facing degrees
          • Set testCreep[1] = (Last created unit group)
        • Else - Actions
 
  • Do units exist already on map, so the grouping on Map Init works correctly?
  • Why is checked if units in current AND next region are dead?
  • (Last created unit group) does always create a copy group for you, instead of returning the real "Last created group".
    So when you always overwrite one same group variable with a new (Last created unit group), it will cause a leak. Things That Leak
    You can even just use one temporary group, to count enemies, and then instantly destroy it.
  • You can use a loop to find the correct region[index] instead of putting all in single if conditions. [GUI] - [How-to] Loop In GUI!
 
Level 39
Joined
Feb 27, 2007
Messages
4,994
You should use the creepRegions[] variables in the lines that set SecretCreepPoints[].

  • BanditCreepInit
    • Events
      • Map initialization
    • Conditions
    • Actions
      • Set creepRegions[1] = secretCreep1 <gen>
      • Set creepRegions[2] = secretCreep2 <gen>
      • Set creepRegions[3] = secretCreep3 <gen>
      • Set creepRegions[4] = secretCreep4 <gen>
      • Set creepRegions[5] = secretCreep5 <gen>
      • Set creepRegions[6] = secretCreep6 <gen>
      • For each (Integer A) from 1 to 6 do (Actions)
        • Loop - Actions
          • Set testCreep[(Integer A)] = (Units in creepRegions[(Integer A)])
          • set SecretCreepPoints[(Integer A)] = Center of creepRegions[(Integer A)]
Since you have the array stuff all set up already I would just use a simple loop over the 1-6 indices and just clear/re-use the group variables (which doesn't 'cause' a leak, since you're reusing the object). You'll have to spawn the units sequentially with a second loop to do that, though. Be aware that Integer A and Integer B are global variables that can get messed up if, for example, this trigger creates units in a B loop and another trigger runs when a unit enters the map that also uses an Integer B loop. You can avoid this problem by making sure there are no conflicts beforehand or using a different custom integer variable for different loops that can interact with each other.

Conditions are executed in order until one is found to be false, so you can save some checks by putting the 'unit in group' check first. Also you'll have to set testCreep[7] = testCreep[1] and SecretCreepPoints[7] = SecretCreepPoints[1] after they're assigned so the loop can wrap around properly when units are in the 6th creep group.

  • BanditCreepSpawn
    • Events
      • Unit - A unit Dies
    • Conditions
      • (Unit-type of (Triggering unit)) Equal to Bandit (secret creep)
    • Actions
      • For each (Integer A) from 1 to 6 do (Actions)
        • Loop - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • ((Triggering unit) is in testCreep[(Integer A)]) Equal to True
              • (All units of testCreep[(Integer A)] are dead) Equal to True
              • (All units of testCreep[(Integer A) + 1] are dead) Equal to True
            • Then - Actions
              • Unit Group - Remove all units from testCreep[(Integer A)] //this is called "clear" in the actions menu
              • Unit Group - Remove all units from testCreep[(Integer A) + 1]
              • For each (Integer B) from 1 to 6 do (Actions)
                • Loop - Actions
                  • Unit - Create 1 Bandit (secret creep) for Neutral Hostile at SecretCreepPoints[(Integer A) + 1] facing Default building facing degrees
                  • Unit Group - Add (Last created unit) to testCreep[(Integer A) + 1]
              • Custom script: exitwhen true //this exits the loop immediately instead of looking at the rest of the possible groups
            • Else - Actions
 
Level 1
Joined
Apr 20, 2019
Messages
2
Thank you, this is good stuff about loops.
I couldn't destroy unit group, because, no matter where I put the destroy call it destroyed it before condition check in next loop, so creeps just didn't spawn.(most likely I just don't really understand how that works yet).
This is what I crystallized:
  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
    • If - Conditions
      • (All units of testCreep[1] are dead) Equal to True
      • (All units of testCreep[2] are dead) Equal to True
      • ((Triggering unit) is in testCreep[1]) Equal to True
    • Then - Actions
      • Custom script: call DestroyGroup(udg_testCreep[2])
      • Unit - Create 6 Bandit (secret creep) for Neutral Hostile at SecretCreepPoints[2] facing Default building facing degrees
      • Set testCreep[2] = (Last created unit group)
    • Else - Actions
But it didn't work.

Removing dead units from unitgroup with Clear and adding new spawns in is very good way. [solution to my problem]

Thank you guys for showing more effective ways. And How-to about loops as very helpful.
 
Last edited:
Level 39
Joined
Feb 27, 2007
Messages
4,994
The right place to destroy it was where you tried, and your intuition is correct. The existing group data object will be 'lost' when testCreep[2] is reassigned = (Last created unit group), so it needs to be destroyed before that happens. What you wrote looks to me like it should have worked, though I have specifically never actually used Last created unit group after creating multiple units. I assume that's how it was intended to be used but am not sure.
 
Status
Not open for further replies.
Top