• 🏆 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!

Kill summoned units by summoner if summoner dies

Status
Not open for further replies.
Level 11
Joined
Jul 17, 2013
Messages
544
As thread name says i have summoner that has summon skill based on summon water element, i need all summons sumonned by summoner to die right when summoner dies. the hardest thing in this is that it has to be MUI i got like 30 summoners in my map this is what makes this more difficult. i have got unit indexer in my map but how can i use it for my purposes?
 
Level 39
Joined
Feb 27, 2007
Messages
5,013
Use a unit group array to keep track of units owned by a summoner, where you use the unit’s index (custom value) as the array index. This ‘attaches’ the group to the summoner.

When a summoner summons a unit (there’s an event for this), check to see if that summoner’s group exists. If not, create the group; then always add the summoned unit to the group.

When a summoner dies, kill all the units in the group and destroy the group.
 

Uncle

Warcraft Moderator
Level 64
Joined
Aug 10, 2018
Messages
6,539
To elaborate on what Pyro said because a lot of GUI'ers don't know about this. Unit Group arrays need to have their Size manually set in order to take advantage of their Array-at least when working with GUI. This can be an issue if you're using Custom Value as the [index] since this value will differ from unit to unit.

The solution is to manually create the Unit Groups yourself like so:
  • Events
    • Unit - A unit spawns a Summoned unit
  • Conditions
    • // It was a Summoner
  • Actions
    • Set Variable CV = Custom value of (Summoning unit)
    • Custom script: if (udg_SummonGroup[udg_CV] == null ) then
    • Custom script: set udg_SummonGroup[udg_CV] = CreateGroup()
    • Custom script: endif
    • Unit Group - Add (Summoned unit) to SummonGroup[CV]
Then destroy the group like so:
  • Events
    • Unit - A unit dies
  • Conditions
    • // It was a Summoner
  • Actions
    • Set Variable CV = Custom value of (Triggering unit)
    • Unit Group - Pick every unit in SummonGroup[CV] and do (Actions)
      • Loop - Actions
        • Unit - Kill (Picked unit)
    • Custom script: call DestroyGroup(udg_SummonGroup[udg_CV])
Keep in mind that any Summoned units that died prior to the Summoner dying will still be stored in the Unit Group. This is fine in this case since your intention is to kill them anyway, but it can cause some funky interactions. For example, if you created a Special Effect on each (Picked unit), this would create the effect on already dead units as well (if they haven't fully decayed yet).
 
Last edited:
Level 11
Joined
Jul 17, 2013
Messages
544
To elaborate on what Pyro said because a lot of GUI'ers don't know about this. Unit Group arrays need to have their Size manually set in order to take advantage of their Array-at least when working with GUI. This can be an issue if you're using Custom Value as the [index] since this value will differ from unit to unit.

The solution is to manually create the Unit Groups yourself like so:
  • Events
    • Unit - A unit spawns a Summoned unit
  • Conditions
    • // It was a Summoner
  • Actions
    • Set Variable CV = Custom value of (Summoning unit)
    • Custom script: if (udg_SummonGroup[udg_CV] == null ) then
    • Custom script: set udg_SummonGroup[udg_CV] = CreateGroup()
    • Custom script: endif
    • Unit Group - Add (Summoned unit) to SummonGroup[CV]
Then destroy the group like so:
  • Events
    • Unit - A unit dies
  • Conditions
    • // It was a Summoner
  • Actions
    • Set Variable CV = Custom value of (Triggering unit)
    • Unit Group - Pick every unit in SummonGroup[CV] and do (Actions)
      • Loop - Actions
        • Unit - Kill (Picked unit)
    • Custom script: call DestroyGroup(udg_SummonGroup[udg_CV])
Keep in mind that any Summoned units that died prior to the Summoner dying will still be stored in the Unit Group. This is fine in this case since your intention is to kill them anyway, but it can cause some funky interactions. For example, if you created a Special Effect on each (Picked unit), this would create the effect on already dead units as well (if they haven't fully decayed yet).


do i also create varriable SummonGroup array at varriable creator? i think i have to else i cant use it at action


Unit Group - Add (Summoned unit) to SummonGroup[CV]
 
Level 11
Joined
Jul 17, 2013
Messages
544
Anyway i think i have found easier way, what do you think about it? i set custom value of spawned units to besame as custom value of unit who spawns them then when spawning unit dies i kill units that have same custom value


i wantto ask u for opinion because you didnt suggest it so im wondering if units with same custom values can cause issues

1661803347514.png

1661803376886.png
 

Uncle

Warcraft Moderator
Level 64
Joined
Aug 10, 2018
Messages
6,539
If you use a Unit Indexer then you really shouldn't EVER Set the custom value of a unit yourself as that defeats the whole purpose of the system. It also makes any custom triggers you have that take advantage of Unit Indexing at risk of causing bugs.

But it looks like you only want to Kill Summons that are near the dying Summoner, rather than what you originally asked for "i need all summons sumonned by summoner to die right when summoner dies". If that's the case then just use a Unit array variable like so:
  • Events
    • Unit - A unit spawns a Summoned unit
  • Conditions
    • (Unit-type of (Summoning unit)) Equal to Snow Wolf Matriach
  • Actions
    • Set Variable CV = Custom value of (Summoned unit)
    • Set Variable Summoner[CV] = (Summoning unit)
Then kill the summons like so:
  • Events
    • Unit - A unit dies
  • Conditions
    • (Unit-type of (Dying unit)) Equal to Snow Wolf Matriach
  • Actions
    • Set Variable TempLoc = (Position of (Dying unit))
    • Set Variable TempGroup = (Units within 450.00 of TempLoc matching (Summoner[Custom value of (Matching unit)] Equal to (Dying unit) and...)
    • Unit Group - Pick every unit in TempGroup and do (Actions)
      • Loop - Actions
        • Unit - Kill (Picked unit)
    • Custom script: call DestroyGroup(udg_TempGroup)
So Summoner[CV] is tracking the Summoner and linking it to the Summon, very similar to what you're doing now but taking advantage of the Unit Indexer.

Otherwise, I would just use my original triggers. And to answer your question, yes, SummonGroup is a Unit Group array variable which you need to create yourself.
 
Last edited:
Level 11
Joined
Jul 17, 2013
Messages
544
I have 1 more question i am worried about, custom values of my summoners are numbers from 1530 up to 1550 if max index of my array unit is for example 1550 then wont it allocate 1550 places in memory even tho most of them are empty? im just afraid of memory leaks
 

Uncle

Warcraft Moderator
Level 64
Joined
Aug 10, 2018
Messages
6,539
I have 1 more question i am worried about, custom values of my summoners are numbers from 1530 up to 1550 if max index of my array unit is for example 1550 then wont it allocate 1550 places in memory even tho most of them are empty? im just afraid of memory leaks
The max array size of a variable is 32,768, so as long as your map doesn't have 32,768 units at the same time you'll be fine. Also, Bribe's Unit Indexing system recycles unused custom values, meaning if a unit dies then it's Custom Value becomes available to use by a newly created unit. So it's extremely hard to reach this limit since you need 32,768 units all living at the same time.

But more importantly, you don't need to set the default size of most Arrays. Keeping their array size at 1 will cause them to automatically adjust when needed.

HOWEVER, Unit Groups, Player Groups, and Timers are the exception to this rule and won't work properly if you simply rely on the default array size of 1. But there's a workaround where you can Create the Group/Timer yourself using Custom script which fixes this issue, which is what I'm doing in my first trigger:
  • Custom script: set udg_SummonGroup[udg_CV] = CreateGroup()
Also, you're correct about the max index allocating 1550 places in memory despite most being empty, but those are NOT memory leaks and it's really not an issue to have a lot of Array variables.

A memory leak is when you lose track of something and cannot get rid of it. Some things in Warcraft 3 will automatically destroy/remove themselves so it's not always a problem, but certain things do cause memory leaks if you don't destroy/remove them yourself. For example, this trigger has a memory leak:
  • Set Variable TempLoc = Center of map
  • Special Effect - Create a Thunderclap special effect at TempLoc
  • Special Effect - Create a Thunderclap special effect at TempLoc
  • Special Effect - Destroy (Last created effect)
  • Custom script: call RemoveLocation(udg_TempLoc)
We're properly managing the Point memory leak by using TempLoc and then Removing it, HOWEVER, we never Destroy our first Thunderclap special effect, and now we can never destroy it because we've lost track of it. We either have to Destroy it BEFORE creating the second Special Effect or store it in a variable so we can keep track of it and destroy it later on. It's the act of "losing track of it" that makes it a memory leak.
 
Last edited:
Status
Not open for further replies.
Top