• 🏆 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!
  • 🏆 Hive's 6th HD Modeling Contest: Mechanical is now open! Design and model a mechanical creature, mechanized animal, a futuristic robotic being, or anything else your imagination can tinker with! 📅 Submissions close on June 30, 2024. Don't miss this opportunity to let your creativity shine! Enter now and show us your mechanical masterpiece! 🔗 Click here to enter!

[Solved] Check amount of spell-affected units

Status
Not open for further replies.
Level 3
Joined
Apr 10, 2023
Messages
12
Hi,
is there a way to check how many units are affected by a certain spell or aura?

Scenario:
Unit A emits an aura in a certain radius. A certain number of units B are in this radius and thus benefit from the aura's effect. Is it possible to tell how many units B are affected by it (and run a trigger if a fixed amount is met).

(Units A and B are buildings but can be placed by the player, meaning they don't have a fixed location)

Any help will be highly appreciated :D
 

Uncle

Warcraft Moderator
Level 64
Joined
Aug 10, 2018
Messages
6,596
Hello, you can check when units have a buff using a Boolean comparison (condition). You can use the Pick Every Unit action to enumerate over a group of units. You can also store units into a Unit Group variable and do things like check how many units are contained inside.

Here's an example (I'm writing this trigger from memory):
  • Set Variable Point = (Position of (Unit A))
  • Set Variable UnitGroup = (Units within 1000.00 range of Point matching ((Matching unit) has buff YourAuraBuff Equal to True))
  • Set Variable BuffCount = (Number of units in UnitGroup)
  • If BuffCount Greater than or Equal to 5 then Trigger - Run MyOtherTrigger (ignoring conditions)
BuffCount is an Integer variable that will be equal to the number of units in UnitGroup.
UnitGroup is a Unit Group variable that will only contain units that have your desired buff and are within 1000.00 range of Point.
Point is a Point variable which we set to the position of "Unit A".

The Event for this trigger could be A Unit Finishes Construction since that runs whenever a Structure finishes building.

If you can have multiple Unit A's then you would probably want to store them in a Unit Group so you run these Actions once for each of them.
 
Level 3
Joined
Apr 10, 2023
Messages
12
Hello, you can check when units have a buff using a Boolean comparison (condition). You can use the Pick Every Unit action to enumerate over a group of units. You can also store units into a Unit Group variable and do things like check how many units are contained inside.

Here's an example (I'm writing this trigger from memory):
  • Set Variable Point = (Position of (Unit A))
  • Set Variable UnitGroup = (Units within 1000.00 range of Point matching ((Matching unit) has buff YourAuraBuff Equal to True))
  • Set Variable BuffCount = (Number of units in UnitGroup)
  • If BuffCount Greater than or Equal to 5 then Trigger - Run MyOtherTrigger (ignoring conditions)
BuffCount is an Integer variable that will be equal to the number of units in UnitGroup.
UnitGroup is a Unit Group variable that will only contain units that have your desired buff and are within 1000.00 range of Point.
Point is a Point variable which we set to the position of "Unit A".

The Event for this trigger could be A Unit Finishes Construction since that runs whenever a Structure finishes building.

If you can have multiple Unit A's then you would probably want to store them in a Unit Group so you run these Actions once for each of them.
Thank you for your answer :D I'm completely new to mapping, so I have further questions about multiple Units A:

If there are several Units A, how do you run this for each one seperately (Unit A1 affects 7 Units B with its effect, Unit A2 affects 4 Units B.)
& What if a Unit B is in the radius of several Units A?
 

Uncle

Warcraft Moderator
Level 64
Joined
Aug 10, 2018
Messages
6,596
It's a little complicated but I managed it using some Unit Groups and the Unit Indexing method.

The variable BC_Amount[] is tied to each UnitA-type building and is equal to how many UnitB units are within 600.00 range of them. You can adjust these values of oourse.
 

Attachments

  • Building Count Check 1.w3m
    24.6 KB · Views: 3
Level 3
Joined
Apr 10, 2023
Messages
12
It's a little complicated but I managed it using some Unit Groups and the Unit Indexing method.

The variable BC_Amount[] is tied to each UnitA-type building and is equal to how many UnitB units are within 600.00 range of them. You can adjust these values of oourse.
Thank you for all the help. Unfortunately, I get an error while opening this map in the editor: "Level Info data missing or invalid". Do i have to use another program to open it?
 

Uncle

Warcraft Moderator
Level 64
Joined
Aug 10, 2018
Messages
6,596
You need the latest patch of Warcraft 3 to open it.
Here are the triggers:
  • BC Finish Constructing A
    • Events
      • Unit - A unit Finishes construction
    • Conditions
      • (Unit-type of (Constructed structure)) Equal to UnitA
    • Actions
      • Set VariableSet BC_UnitA = (Constructed structure)
      • Set VariableSet BC_CV = (Custom value of BC_UnitA)
      • Unit Group - Add BC_UnitA to BC_GroupA
      • -------- --------
      • Set VariableSet BC_Point[0] = (Position of BC_UnitA)
      • -------- --------
      • Unit Group - Pick every unit in BC_GroupB and do (Actions)
        • Loop - Actions
          • Set VariableSet BC_UnitB = (Picked unit)
          • -------- --------
          • Set VariableSet BC_Point[1] = (Position of BC_UnitB)
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (Distance between BC_Point[0] and BC_Point[1]) Less than or equal to 600.00
            • Then - Actions
              • Set VariableSet BC_Amount[BC_CV] = (BC_Amount[BC_CV] + 1)
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • BC_Amount[BC_CV] Greater than or equal to 5
                • Then - Actions
                  • Trigger - Run BC Amount Is Met <gen> (ignoring conditions)
                • Else - Actions
            • Else - Actions
          • Custom script: call RemoveLocation(udg_BC_Point[1])
  • BC Finish Constructing B
    • Events
      • Unit - A unit Finishes construction
    • Conditions
      • (Unit-type of (Constructed structure)) Equal to UnitB
    • Actions
      • Set VariableSet BC_UnitB = (Constructed structure)
      • Unit Group - Add BC_UnitB to BC_GroupB
      • -------- --------
      • Set VariableSet BC_Point[1] = (Position of BC_UnitB)
      • -------- --------
      • Unit Group - Pick every unit in BC_GroupA and do (Actions)
        • Loop - Actions
          • Set VariableSet BC_UnitA = (Picked unit)
          • Set VariableSet BC_CV = (Custom value of BC_UnitA)
          • -------- --------
          • Set VariableSet BC_Point[0] = (Position of BC_UnitB)
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (Distance between BC_Point[0] and BC_Point[1]) Less than or equal to 600.00
            • Then - Actions
              • Set VariableSet BC_Amount[BC_CV] = (BC_Amount[BC_CV] + 1)
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • BC_Amount[BC_CV] Greater than or equal to 5
                • Then - Actions
                  • Trigger - Run BC Amount Is Met <gen> (ignoring conditions)
                • Else - Actions
            • Else - Actions
          • Custom script: call RemoveLocation(udg_BC_Point[0])
      • -------- --------
      • Custom script: call RemoveLocation(udg_BC_Point[1])
  • BC Building Dies
    • Events
      • Unit - A unit Dies
    • Conditions
    • Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Unit-type of (Triggering unit)) Equal to UnitA
        • Then - Actions
          • -------- Reset variables related to UnitA: --------
          • Unit Group - Remove (Triggering unit) from BC_GroupA.
          • Set VariableSet BC_Amount[(Custom value of (Triggering unit))] = 0
        • Else - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (Unit-type of (Triggering unit)) Equal to UnitB
            • Then - Actions
              • -------- Reset variables related to UnitB: --------
              • Unit Group - Remove (Triggering unit) from BC_GroupB.
            • Else - Actions
  • BC Amount Is Met
    • Events
    • Conditions
    • Actions
      • -------- Do whatever you want here: --------
      • -------- --------
      • -------- Here I am looping over all of the UnitB units that UnitA was affecting with it's aura: --------
      • -------- BC_Point[0] is the position of the Aura building! --------
      • Set VariableSet BC_AffectedGroup = (Units within 600.00 of BC_Point[0].)
      • -------- --------
      • Unit Group - Pick every unit in BC_AffectedGroup and do (Actions)
        • Loop - Actions
          • Set VariableSet BC_UnitB = (Picked unit)
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (Unit-type of BC_UnitB) Equal to UnitB
              • (BC_UnitB is alive) Equal to True
            • Then - Actions
              • Special Effect - Create a special effect attached to the origin of BC_UnitB using Abilities\Spells\Orc\WarStomp\WarStompCaster.mdl
              • Special Effect - Destroy (Last created special effect)
            • Else - Actions
      • -------- --------
      • Custom script: call DestroyGroup(udg_BC_AffectedGroup)
Variables:
BC_GroupA = Unit Group
BC_GroupB = Unit Group
BC_AffectedGroup = Unit Group
BC_Point = Point (array)
BC_CV = Integer
BC_Amount = Integer (array)
BC_UnitA = Unit
BC_UnitB = Unit

This requires a Unit Indexer system in your map as well. I linked it earlier (or you can check my signature).
 

Uncle

Warcraft Moderator
Level 64
Joined
Aug 10, 2018
Messages
6,596
No problem, but I realized there is a bug assuming your buildings can be destroyed. Whenever a UnitB is destroyed (dies), you need to find all UnitA's around it that are within Aura range and subtract 1 from their BC_Amount[]. It would be very similar to the BC Finish Constructing B trigger except that the BC_UnitB variable would be set to the (Dying unit) and you would subtract instead of add BC_Amount.

There could also be some issues depending on what you're doing in your BC Amount Is Met trigger.
 
Last edited:
Status
Not open for further replies.
Top