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

Usings waits with unit group

Status
Not open for further replies.
Level 7
Joined
Feb 23, 2020
Messages
253
Hello, this trigger works almost correctly except for the wait funtion, if the integer number equals to 1 two times in a row the second wait gets over written, how do i make this function properly?

NOTE: This is NOT supposed to work on multiple units. But do i still need to make it MUI?

  • Moraia Attacking
    • Events
      • Unit - A unit Is attacked
    • Conditions
      • (Unit-type of (Attacking unit)) Equal to Moraia
    • Actions
      • Set VariableSet MoraiaAA_Caster = (Attacking unit)
      • Set VariableSet MoraiaAA_Target = (Attacked unit)
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Random integer number between 1 and 2) Equal to 1
        • Then - Actions
          • Animation - Play MoraiaAA_Caster's Spell Throw animation
          • Set VariableSet MoraiaAA_Point = (Position of MoraiaAA_Target)
          • Set VariableSet MoraiaAA_SPXPoint = (Position of MoraiaAA_Target)
          • Set VariableSet MoraiaAA_Group = (Units within 300.00 of MoraiaAA_Point.)
          • Special Effect - Create a special effect at MoraiaAA_SPXPoint using Objects\Spawnmodels\Demon\InfernalMeteor\InfernalMeteor.mdl
          • Special Effect - Destroy (Last created special effect)
          • Wait 2.50 seconds
          • Unit Group - Pick every unit in MoraiaAA_Group and do (Actions)
            • Loop - Actions
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • ((Picked unit) belongs to an enemy of (Owner of MoraiaAA_Caster).) Equal to True
                • Then - Actions
                  • Unit - Cause MoraiaAA_Caster to damage (Picked unit), dealing (Real((Base Damage of MoraiaAA_Caster for weapon index 0))) damage of attack type Spells and damage type Normal
                • Else - Actions
          • Custom script: call DestroyGroup(udg_MoraiaAA_Group)
          • Custom script: call RemoveLocation(udg_MoraiaAA_Point)
          • Custom script: call RemoveLocation(udg_MoraiaAA_SPXPoint)
        • Else - Actions
 
Level 7
Joined
Feb 23, 2020
Messages
253
Local variables (custom script) can do this. Otherwise you will need to work out some sort of storage/instancing system to hold the value during the wait.
Alright, is it like a simple custom script or is it required to use multiple?
 

Uncle

Warcraft Moderator
Level 64
Joined
Aug 10, 2018
Messages
6,583
What is happening is MoraiaAA_Group is being set every time the effect goes off, which actually empties the Unit Group and rebuilds it. This could remove previous units from the group (although potentially adding them back again) who were waiting in line to get damaged. This could result in a unit not taking damage because it's removed from the group before the 2.50 seconds has passed.

Anyway, it's a fairly simple fix using Custom script and a method that allows you to make Global variables act as Local variables (to a certain extent):
  • Example
    • Events
      • Unit - A unit Is attacked
    • Conditions
    • Actions
      • Custom script: local group udg_tempGroup
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Random integer number between 1 and 2) Equal to 1
        • Then - Actions
          • Set VariableSet tempPoint = (Position of (Triggering unit))
          • Custom script: set udg_tempGroup = CreateGroup()
          • Custom script: call GroupEnumUnitsInRangeOfLoc(udg_tempGroup, udg_tempPoint, 300, null)
          • Custom script: call RemoveLocation (udg_tempPoint)
          • Wait 2.50 seconds
          • Unit Group - Pick every unit in tempGroup and do (Actions)
            • Loop - Actions
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • ((Picked unit) is alive) Equal to True
                  • ((Picked unit) belongs to an enemy of (Owner of (Triggering unit)).) Equal to True
                • Then - Actions
                  • Unit - Cause (Triggering unit) to damage (Picked unit), dealing 10.00 damage of attack type Spells and damage type Normal
                • Else - Actions
          • Custom script: call DestroyGroup (udg_tempGroup)
        • Else - Actions
      • Custom script: set udg_tempGroup = null
So all you need is 2 Variables for this trigger:
tempPoint = Point
tempGroup = Unit Group

If you rename these variables then make sure to adjust their names in the Custom script or you'll get errors.

If you want to increase the Radius (aka Area of Effect) you need to adjust the "300" in this line:
  • Custom script: call GroupEnumUnitsInRangeOfLoc(udg_tempGroup, udg_tempPoint, 300, null)
Also, make sure to put:
  • ((Picked unit) is alive) Equal to True
In your Conditions, otherwise Dead units will be targeted as well. You wouldn't notice any problems in this particular case because you were only dealing damage to the Picked units (trying to damage a dead unit does nothing) but it's good practice and more efficient to avoid doing unnecessary things.


Lastly, an actual explanation. The reason this works is because it creates a NEW Unit Group each time the effect goes off. This new Unit Group is unique from the other Unit Groups that the effect can create. Because of this, you get around the issue that you run into with Global variables, where only one instance of it can exist at a time and therefore it doesn't always do what you need. This is the nature of Local variables and it's why they're so useful. If you're still confused, I recommend googling the difference between Locals/Globals. So in your original trigger there can only ever be one MoraiaAA_Group, and that's the source of the problem which I explained at the start of my post.
 

Attachments

  • Local Group example.w3m
    17.6 KB · Views: 17
Last edited:
Level 7
Joined
Feb 23, 2020
Messages
253
What is happening is MoraiaAA_Group is being set every time the effect goes off, which actually empties the Unit Group and rebuilds it. This could remove previous units from the group (although potentially adding them back again) who were waiting in line to get damaged. This could result in a unit not taking damage because it's removed from the group before the 2.50 seconds has passed.

Anyway, it's a fairly simple fix using Custom script and a method that allows you to make Global variables act as Local variables (to a certain extent):
  • Example
    • Events
      • Unit - A unit Is attacked
    • Conditions
    • Actions
      • Custom script: local group udg_tempGroup
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Random integer number between 1 and 2) Equal to 1
        • Then - Actions
          • Set VariableSet tempPoint = (Position of (Triggering unit))
          • Custom script: set udg_tempGroup = CreateGroup()
          • Custom script: call GroupEnumUnitsInRangeOfLoc(udg_tempGroup, udg_tempPoint, 300, null)
          • Custom script: call RemoveLocation (udg_tempPoint)
          • Wait 2.50 seconds
          • Unit Group - Pick every unit in tempGroup and do (Actions)
            • Loop - Actions
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • ((Picked unit) is alive) Equal to True
                  • ((Picked unit) belongs to an enemy of (Owner of (Triggering unit)).) Equal to True
                • Then - Actions
                  • Unit - Cause (Triggering unit) to damage (Picked unit), dealing 10.00 damage of attack type Spells and damage type Normal
                • Else - Actions
          • Custom script: call DestroyGroup (udg_tempGroup)
        • Else - Actions
      • Custom script: set udg_tempGroup = null
So all you need is 2 Variables for this trigger:
tempPoint = Point
tempGroup = Unit Group

If you rename these variables then make sure to adjust their names in the Custom script or you'll get errors.

If you want to increase the Radius (aka Area of Effect) you need to adjust the "300" in this line:
  • Custom script: call GroupEnumUnitsInRangeOfLoc(udg_tempGroup, udg_tempPoint, 300, null)
Also, make sure to put:
  • ((Picked unit) is alive) Equal to True
In your Conditions, otherwise Dead units will be targeted as well. You wouldn't notice any problems in this particular case because you were only dealing damage to the Picked units (trying to damage a dead unit does nothing) but it's good practice and more efficient to avoid doing unnecessary things.


Lastly, an actual explanation. The reason this works is because it creates a NEW Unit Group each time the effect goes off. This new Unit Group is unique from the other Unit Groups that the effect can create. Because of this, you get around the issue that you run into with Global variables, where only one instance of it can exist at a time and therefore it doesn't always do what you want. This is the nature of Local variables and it's why they're so useful. If you're still confused, I recommend googling the difference between Locals/Globals. So in your original trigger there can only ever be one MoraiaAA_Group, and that's the source of the problem which I explained at the start of my post.

Thank you mean, using custom scripts like this is completely new to me, is there anywhere i can read about them to learn?
 

Uncle

Warcraft Moderator
Level 64
Joined
Aug 10, 2018
Messages
6,583
I'd just google "Hiveworkshop Custom script", you should see a bunch of Tutorials/posts that will help you out.

A quick explanation:

Custom script is just Jass, the programming language Warcraft 3 uses. You're actually coding in Jass when you make your own triggers, you just don't realize it because you're using GUI (a Graphical User Interface) which hides the code behind easy to understand/use buttons. So you really want to learn about Jass instead, since that's what Custom script is.

If you Convert your trigger to Custom Text (I think it's under Edit) you can see exactly what I mean. Just make sure to make a backup of the trigger first so you don't lose the original, because once you convert a trigger from GUI -> Jass it can't be converted back.

After doing so you'll see all of your Events/Conditions/Actions get changed into pure Jass (code form), and you'll see a lot of familiar names. For example, Triggering Unit will be called "GetTriggerUnit()". What does "GetTriggerUnit()" do? It gets you the Triggering Unit, of course. It's not all that complicated once you get over the initially overwhelming wall of text.

To help you understand better, these two things are exactly the same:
  • Set VariableSet MoraiaAA_Group = (Units within 300.00 of MoraiaAA_Point.)
  • Custom script: set udg_MoraiaAA_Group = CreateGroup()
  • Custom script: call GroupEnumUnitsInRangeOfLoc(udg_MoraiaAA_Group, udg_MoraiaAA_Point 300.00, null)
GUI is great because it simplifies things and packs code together into one single Event/Condition/Action that's easy to read and understand.
 
Last edited:
Level 7
Joined
Feb 23, 2020
Messages
253
I'd just google "Hiveworkshop Custom script", you should see a bunch of Tutorials/posts that will help you out.

A quick explanation:

Custom script is just Jass, the programming language Warcraft 3 uses. You're actually coding in Jass when you make your own triggers, you just don't realize it because you're using GUI (a Graphical User Interface) which hides the code behind easy to understand/use buttons. So you really want to learn about Jass instead, since that's what Custom script is.

If you Convert your trigger to Custom Text (I think it's under Edit) you can see exactly what I mean. Just make sure to make a backup of the trigger first so you don't lose the original, because once you convert a trigger from GUI -> Jass it can't be converted back.

After doing so you'll see all of your Events/Conditions/Actions get changed into pure Jass (code form), and you'll see a lot of familiar names. For example, Triggering Unit will be called "GetTriggerUnit()". What does "GetTriggerUnit()" do? It gets you the Triggering Unit, of course. It's not all that complicated once you get over the initially overwhelming wall of text.

To help you understand better, these two things are exactly the same:
  • Set VariableSet MoraiaAA_Group = (Units within 300.00 of MoraiaAA_Point.)
  • Custom script: set udg_MoraiaAA_Group = CreateGroup()
  • Custom script: call GroupEnumUnitsInRangeOfLoc(udg_MoraiaAA_Group, udg_MoraiaAA_Point 300.00, null)
GUI is great because it simplifies things and packs code together into one single Event/Condition/Action that's easy to read and understand.

Yeah i've tried converting it a few times and trying to read tutorials on JASS but i find it very hard to learn.
 
Status
Not open for further replies.
Top