• 🏆 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] Alright, i did a thing, does it leak?

Status
Not open for further replies.
Level 5
Joined
Feb 5, 2021
Messages
89
Hello again

Alright, as the title suggests, i did a thing and as a beginner trigger dude, i feel like this will leak if i just use it as it is, am i wrong?

  • SpawnLevel1Mobs
    • Events
    • Conditions
    • Actions
      • Set VariableSet SelectedMobGroup = (Units of type No unit-type)
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • EncounterSelection Equal to 1
        • Then - Actions
          • Set VariableSet SelectedMobGroup = Zone1Thieves
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
            • Then - Actions
              • Set VariableSet MobSpawnPoints = (Random point in Zone1EncounterArea <gen>)
              • Unit - Create (Random integer number between 0 and ((NumberOfPlayers / 2) + 1)) (Unit-type of (Random unit from SelectedMobGroup)) for Neutral Hostile at MobSpawnPoints facing Default building facing degrees
              • Custom script: call RemoveLocation (udg_MobSpawnPoints)
            • Else - Actions
Do i need to destroy the SelectedMobGroup after each time?
 

Uncle

Warcraft Moderator
Level 64
Joined
Aug 10, 2018
Messages
6,539
Yes, you need to destroy SelectedMobGroup each time in this case. Also, your initial setting of it to (Units of type No unit-type) is unnecessary and does nothing.

So whenever you Set SelectedMobGroup you're actually creating an entirely new Unit Group object. The SelectedMobGroup variable is a reference to this newly created Unit Group and not the Unit Group itself. This reference is the reason you're able to interact with the Unit Group and is important to maintain. By Setting SelectedMobGroup again, you're losing reference to the old Unit Group it was referencing and creating a new one to reference.
This old Unit Group is no longer accessible, however, it still exists in the game's memory and takes up precious space (memory leak!).

Imagine there was a hidden file on your computer that you no longer needed but couldn't find to delete. It would take up hard drive space despite not being needed. That's basically what happens with memory leaks. Luckily, you can take steps to prevent memory leaks by making sure to destroy/remove (interchangeable terminology) these objects before you lose reference to them.

Also, understand that it's possible to use Unit Groups in a more permanent manner instead of constantly creating/destroying them. We have actions like Clear Unit Group, Add to Unit Group, Remove from Unit Group, etc. which all provide a way to manage a Unit Group without needing to destroy it and recreate it. This can be useful in certain situations depending on what you're trying to do.

With all of that in mind, here's how your trigger could work:
  • SpawnMobs
    • Events
    • Conditions
    • Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • EncounterSelection Equal to 1
        • Then - Actions
          • Set VariableSet SelectedMobGroup = Units in Zone1EncounterArea <gen>
          • Set VariableSet MobSpawnPoints = (Random point in Zone1EncounterArea <gen>)
          • Unit - Create (Random integer number between 0 and ((NumberOfPlayers / 2) + 1)) (Unit-type of (Random unit from SelectedMobGroup)) for Neutral Hostile at MobSpawnPoints facing Default building facing degrees
          • Custom script: call RemoveLocation (udg_MobSpawnPoints)
          • Custom script: call DestroyGroup (udg_SelectedMobGroup)
        • Else - Actions
Note that I'm not entirely sure what your intended goal is so there's probably a better way of handling all of this.

If EncounterSelection is Equal to 1 then we gather up all of the units in in the Zone1EncounterArea region, add them to our selected Unit Group, pick one of them at random, and create duplicates of it at some random point. Once that process is over we clean up the memory leaks by destroying the SelectedMobGroup Unit Group and removing the MobSpawnPoints Point (location).

But if Zone1Thieves is a Unit Group that's already been Set beforehand then you can simplify it even further to just this:
  • SpawnMobs
    • Events
    • Conditions
    • Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • EncounterSelection Equal to 1
        • Then - Actions
          • Set VariableSet MobSpawnPoints = (Random point in Zone1EncounterArea <gen>)
          • Unit - Create (Random integer number between 0 and ((NumberOfPlayers / 2) + 1)) (Unit-type of (Random unit from Zone1Thieves)) for Neutral Hostile at MobSpawnPoints facing Default building facing degrees
          • Custom script: call RemoveLocation (udg_MobSpawnPoints)
        • Else - Actions
Again, the solution could change depending on how you want all of this to work.
 
Last edited:
Level 5
Joined
Feb 5, 2021
Messages
89
The one i start where i set it to No unit, i was hoping that could be usef instead of a destroy at the end, honestly only because i was to lazy to find the destroy command :)

But as you said, more context might be needed, so essentially the "SelectedMobGroup" is just a way for me to quickly and easily replicate the summoning process

Context:
I am going to have about 40 unit groups that stores the units that can be "picked from" everytime an encounter happens.

What i want to happen:
1. Encounter happen
2. Randomize EncounterRoller to determine what encounter Will happen
3. Spawn minions in battle area
4. Move heroes
5. Other stuff

So as i said i reallyd dont want to go into the spawning command each time to change that unit groups, instead i am hoping i can just set that one and destroy it when its done so i only have to change 2 things with every replication :')

EDIT:
So, i just thought .. why dont i just make unit group arrays? and then i came up with this, this should pretty much fix all my problems and make it very easy to replicate since its just a matter of setting the group and having the random encounter selector go high enough up :D

  • SpawnLevel1Mobs Copy
    • Events
    • Conditions
    • Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
        • Then - Actions
          • Set VariableSet MobSpawnPoints = (Random point in Zone1EncounterArea <gen>)
          • Unit - Create (Random integer number between 0 and 1 (Unit-type of (Random unit from Zone1Encounters[EncounterSelection])) for Neutral Hostile at MobSpawnPoints facing Default building facing degrees
          • Custom script: call RemoveLocation (udg_MobSpawnPoints)
        • Else - Actions
 
Last edited:
Level 39
Joined
Feb 27, 2007
Messages
5,013
If you're keen on learning to use JASS more directly, there's actually a feature built into Wc3 to do randomized encounters easily: UnitPools are a type that can only be accessed with JASS but basically do everything you want. I wrote (and ultimately never finished) a tutorial about using them many years ago on wc3c, which can still be viewed on the wayback machine here.

So, i just thought .. why dont i just make unit group arrays? and then i came up with this, this should pretty much fix all my problems and make it very easy to replicate since its just a matter of setting the group and having the random encounter selector go high enough up :D
I agree that this should work for you. With a sufficient set of arrays for the regions, it may be possible to compress this random encounter to a single trigger or couple of triggers depending on how they all interact with each other. Keep following this solution and see if you see a way to do so.
 

Uncle

Warcraft Moderator
Level 64
Joined
Aug 10, 2018
Messages
6,539
Remember to initialize the Size of your Unit Group arrays inside the Variable Editor. Unlike most other Variable types, the default Size of 1 will not work.

Also, there's an alternative method using Custom script (Jass) that allows you to keep the Size at it's default value. Simply call the CreateGroup function:
  • Custom script: set udg_EncounterGroups[1] = CreateGroup()
Not really necessary in this case since you're working with a bunch of constants.

And to visualize what Pyrogasm said (also because Arrays are fun) look how clean and organized you can design this to be:
  • Set Variable EncounterAmountMin[1] = 1
  • Set Variable EncounterAmountMax[1] = 4
  • Set Variable EncounterRegion[1] = Zone1EncounterArea <gen>
  • Set Variable EncounterGroup[1] = Units in EncounterRegion[1]
  • --- next encounter
  • Set Variable EncounterAmountMin[2] = 2
  • Set Variable EncounterAmountMax[2] = 6
  • Set Variable EncounterRegion[2] = Zone2EncounterArea <gen>
  • Set Variable EncounterGroup[2] = Units in EncounterRegion[2]
  • --- etc
Now whenever you randomize your EncounterRoller you can plug that integer into the [index] of any of these variables to get the associated data.
  • Set Variable Roll = Random number between 1 and 40
  • Unit - Create (Random integer number between EncounterAmountMin[Roll] and EncounterAmountMax[Roll] (Unit-type of (Random unit from EncounterGroup[Roll]) for Neutral Hostile...
Setting all of these Arrays up beforehand will make all of your future triggers that interact with the Encounter system much easier to manage. I recommend using this approach for just about every aspect of your map. A strong and dynamic foundation will save you 100's of unnecessary triggers/variables and help keep you sane as the map grows in size and complexity.
 
Last edited:
Level 5
Joined
Feb 5, 2021
Messages
89
If you're keen on learning to use JASS more directly, there's actually a feature built into Wc3 to do randomized encounters easily: UnitPools are a type that can only be accessed with JASS but basically do everything you want. I wrote (and ultimately never finished) a tutorial about using them many years ago on wc3c, which can still be viewed on the wayback machine here.


I agree that this should work for you. With a sufficient set of arrays for the regions, it may be possible to compress this random encounter to a single trigger or couple of triggers depending on how they all interact with each other. Keep following this solution and see if you see a way to do so.
Thanks, that is something i will keep in mind for later, right now sadly i do not have the time to study JASS and will keep away from it if possible :)

Remember to initialize the Size of your Unit Group arrays inside the Variable Editor. Unlike most other Variable types, the default Size of 1 will not work.

Also, there's an alternative method using Custom script (Jass) that allows you to keep the Size at it's default value. Simply call the CreateGroup function:
  • Custom script: set udg_EncounterGroups[1] = CreateGroup()
Not really necessary in this case since you're working with a bunch of constants.

And to visualize what Pyrogasm said (also because Arrays are fun) look how clean and organized you can design this to be:
  • Set Variable EncounterAmountMin[1] = 1
  • Set Variable EncounterAmountMax[1] = 4
  • Set Variable EncounterRegion[1] = Zone1EncounterArea <gen>
  • Set Variable EncounterGroup[1] = Units in EncounterRegion[1]
  • --- next encounter
  • Set Variable EncounterAmountMin[2] = 2
  • Set Variable EncounterAmountMax[2] = 6
  • Set Variable EncounterRegion[2] = Zone2EncounterArea <gen>
  • Set Variable EncounterGroup[2] = Units in EncounterRegion[2]
  • --- etc
Now whenever you randomize your EncounterRoller you can plug that integer into the [index] of any of these variables to get the associated data.
  • Set Variable Roll = Random number between 1 and 40
  • Unit - Create (Random integer number between EncounterAmountMin[Roll] and EncounterAmountMax[Roll] (Unit-type of (Random unit from EncounterGroup[Roll]) for Neutral Hostile...
Setting all of these Arrays up beforehand will make all of your future triggers that interact with the Encounter system much easier to manage. I recommend using this approach for just about every aspect of your map. A strong and dynamic foundation will save you 100's of unnecessary triggers/variables and help keep you sane as the map grows in size and complexity.

This looks alot like something i already have set up in another "part" of my map and i believe Pyrogasm helped me with that one :)

And you pretty much did all the work for me here aswell, i will try this as soon as i get the chance! thank you guys!

EDIT:
With this way, would i then be able to remove an encounter after its done?
That could come in handy if possible
 
Last edited:

Uncle

Warcraft Moderator
Level 64
Joined
Aug 10, 2018
Messages
6,539
This explains how to remove an item from an array:
 
Status
Not open for further replies.
Top