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

[Trigger] How to damage a unit once in loop trigger?

Status
Not open for further replies.
Level 5
Joined
Mar 6, 2015
Messages
130
as the title indicates i want to damage units in loop trigger but just one time as you already know if i pick some units inside a loop and tell my caster to damage them every time they take damage multiply times and thats not good because you can`t predict how much damage the units would take in this spell that i made you can see my caster sends a lightning projectile that damage nearby enemies but how can i manage to damage them once?

  • Lightning Bolt Cast
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Lightining Bolt
    • Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • Index_Size Equal to 0
        • Then - Actions
          • Trigger - Turn on Lightning Bolt Loop <gen>
        • Else - Actions
      • Set Index_Size = (Index_Size + 1)
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • Index_Size Greater than IndexM
        • Then - Actions
          • Set Index[Index_Size] = Index_Size
          • Set IndexM = Index_Size
        • Else - Actions
      • Set TempInt = Index[Index_Size]
      • Set Caster[TempInt] = (Casting unit)
      • Set Player[TempInt] = (Owner of Caster[TempInt])
      • Set TempPoint1 = (Position of Caster[TempInt])
      • Set TempPoint2 = (Target point of ability being cast)
      • Set Damage_Amount[TempInt] = 50.00
      • Set Face[TempInt] = (Angle from TempPoint1 to TempPoint2)
      • Set Damage_Range[TempInt] = 300.00
      • Set Speed[TempInt] = 20.00
      • Set Distance[TempInt] = (Distance between TempPoint1 and TempPoint2)
      • Set Level[TempInt] = (Level of (Ability being cast) for Caster[TempInt])
      • Unit - Create 1 Dummy for Player[TempInt] at TempPoint1 facing Face[TempInt] degrees
      • Set Dummy[TempInt] = (Last created unit)
      • Custom script: call RemoveLocation(udg_TempPoint1)
      • Custom script: call RemoveLocation(udg_TempPoint2)
      • Trigger - Turn on Lightning Bolt Loop <gen>
  • Lightning Bolt Loop
    • Events
      • Time - Every 0.03 seconds of game time
    • Conditions
    • Actions
      • For each (Integer Loop_Int) from 1 to Index_Size, do (Actions)
        • Loop - Actions
          • Set TempInt = Index[Loop_Int]
          • Set TempPoint1 = (Position of Dummy[TempInt])
          • Set TempPoint2 = (TempPoint1 offset by Speed[TempInt] towards Face[TempInt] degrees)
          • Set Distance[TempInt] = (Distance[TempInt] - Speed[TempInt])
          • Special Effect - Create a special effect at TempPoint2 using Abilities\Weapons\FarseerMissile\FarseerMissile.mdl
          • Special Effect - Destroy (Last created special effect)
          • Custom script: set bj_wantDestroyGroup=true
          • Unit Group - Pick every unit in (Units within Damage_Range[TempInt] of TempPoint2 matching (((Matching unit) belongs to an enemy of Player[TempInt]) Equal to True)) and do (Actions)
            • Loop - Actions
              • Unit - Cause Caster[TempInt] to damage (Picked unit), dealing (Damage_Amount[TempInt] x (Real(Level[TempInt]))) damage of attack type Spells and damage type Magic
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • Distance[TempInt] Less than or equal to (2.00 x Speed[TempInt])
            • Then - Actions
              • Unit - Add a 1.00 second Generic expiration timer to Dummy[TempInt]
              • Unit - Order Dummy[TempInt] to Human Mountain King - Thunder Clap
              • Set Index_Size = (Index_Size - 1)
              • Set Loop_Int = (Loop_Int - 1)
            • Else - Actions
              • Unit - Move Dummy[TempInt] instantly to TempPoint2, facing Face[TempInt] degrees
          • Custom script: call RemoveLocation(udg_TempPoint1)
          • Custom script: call RemoveLocation(udg_TempPoint2)
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • Index_Size Equal to 0
            • Then - Actions
              • Trigger - Turn off (This trigger)
            • Else - Actions


my demo spell: download
 
Level 18
Joined
May 11, 2012
Messages
2,103
Maybe this can help.
I am using BoL_UnitGroup to filter out the units that were already damaged.


  • Ball Of Lightning
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Ball Of Light
    • Actions
      • -------- ================================================ --------
      • Set BoL_MaxIndex = (BoL_MaxIndex + 1)
      • Set BoL_TrigUnit[BoL_MaxIndex] = (Triggering unit)
      • Set BoL_SpellLvl[BoL_MaxIndex] = (Level of Ball Of Light for BoL_TrigUnit[BoL_MaxIndex])
      • Set BoL_DamageDealt[BoL_MaxIndex] = BoL_Damage[BoL_SpellLvl[BoL_MaxIndex]]
      • Set BoL_Point[1] = (Position of BoL_TrigUnit[BoL_MaxIndex])
      • Set BoL_Point[2] = (Target point of ability being cast)
      • Set BoL_PointDistance[BoL_MaxIndex] = (Position of BoL_TrigUnit[BoL_MaxIndex])
      • Set BoL_Angle[BoL_MaxIndex] = (Angle from BoL_Point[1] to BoL_Point[2])
      • -------- ================================================ --------
      • Unit - Create 1 Ball Of Lightning for (Triggering player) at BoL_Point[1] facing Default building facing degrees
      • Set BoL_Dummy[BoL_MaxIndex] = (Last created unit)
      • -------- ================================================ --------
      • Custom script: set udg_BoL_UnitGroup[udg_BoL_MaxIndex] = CreateGroup()
      • Sound - Play BallOfLightning <gen> at 100.00% volume, located at BoL_Point[1] with Z offset 0.00
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • BoL_MaxIndex Equal to 1
        • Then - Actions
          • Trigger - Turn on Ball Of Lightning Loop <gen>
        • Else - Actions
      • -------- ================================================ --------
      • Custom script: call RemoveLocation(udg_BoL_Point[1])
      • Custom script: call RemoveLocation(udg_BoL_Point[2])
      • Custom script: set udg_BoL_Point[1] = null
      • Custom script: set udg_BoL_Point[2] = null
  • Ball Of Lightning Loop
    • Events
      • Time - Every 0.03 seconds of game time
    • Conditions
    • Actions
      • -------- ================================================ --------
      • For each (Integer BoL_Loop) from 1 to BoL_MaxIndex, do (Actions)
        • Loop - Actions
          • -------- ================================================ --------
          • Set BoL_Point[1] = (Position of BoL_Dummy[BoL_Loop])
          • -------- ================================================ --------
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (Distance between BoL_Point[1] and BoL_PointDistance[BoL_Loop]) Greater than or equal to 1500.00
            • Then - Actions
              • -------- ================================================ --------
              • Unit - Kill BoL_Dummy[BoL_Loop]
              • -------- ================================================ --------
              • Set BoL_TrigUnit[BoL_Loop] = BoL_TrigUnit[BoL_MaxIndex]
              • Set BoL_TrigUnit[BoL_MaxIndex] = No unit
              • Set BoL_Dummy[BoL_Loop] = BoL_Dummy[BoL_MaxIndex]
              • Set BoL_Dummy[BoL_MaxIndex] = No unit
              • Set BoL_SpellLvl[BoL_Loop] = BoL_SpellLvl[BoL_MaxIndex]
              • Set BoL_DamageDealt[BoL_Loop] = BoL_DamageDealt[BoL_MaxIndex]
              • Set BoL_Angle[BoL_Loop] = BoL_Angle[BoL_MaxIndex]
              • Custom script: call DestroyGroup(udg_BoL_UnitGroup[udg_BoL_Loop])
              • Custom script: call RemoveLocation(udg_BoL_PointDistance[udg_BoL_Loop])
              • Set BoL_UnitGroup[BoL_Loop] = BoL_UnitGroup[BoL_MaxIndex]
              • Set BoL_PointDistance[BoL_Loop] = BoL_PointDistance[BoL_MaxIndex]
              • Custom script: set udg_BoL_UnitGroup[udg_BoL_MaxIndex] = null
              • Custom script: set udg_BoL_PointDistance[udg_BoL_MaxIndex] = null
              • Set BoL_MaxIndex = (BoL_MaxIndex - 1)
              • Set BoL_Loop = (BoL_Loop - 1)
              • -------- ================================================ --------
            • Else - Actions
              • -------- ================================================ --------
              • Set BoL_Point[2] = (BoL_Point[1] offset by 20.00 towards BoL_Angle[BoL_Loop] degrees)
              • -------- ================================================ --------
              • Custom script: set bj_wantDestroyGroup = true
              • Unit Group - Pick every unit in (Units within 150.00 of BoL_Point[1]) and do (Actions)
                • Loop - Actions
                  • Set TempUnit = (Picked unit)
                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    • If - Conditions
                      • (TempUnit is A structure) Equal to False
                      • (TempUnit belongs to an enemy of (Owner of BoL_TrigUnit[BoL_Loop])) Equal to True
                      • (TempUnit is dead) Equal to False
                      • (TempUnit is in BoL_UnitGroup[BoL_Loop]) Equal to False
                    • Then - Actions
                      • Unit - Cause BoL_TrigUnit[BoL_Loop] to damage TempUnit, dealing BoL_DamageDealt[BoL_Loop] damage of attack type Spells and damage type Normal
                      • Unit Group - Add TempUnit to BoL_UnitGroup[BoL_Loop]
                    • Else - Actions
              • Unit - Move BoL_Dummy[BoL_Loop] instantly to BoL_Point[2]
              • -------- ================================================ --------
              • Custom script: call RemoveLocation(udg_BoL_Point[2])
              • -------- ================================================ --------
          • -------- ================================================ --------
          • Custom script: call RemoveLocation(udg_BoL_Point[1])
      • -------- ================================================ --------
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • BoL_MaxIndex Equal to 0
        • Then - Actions
          • Trigger - Turn off (This trigger)
        • Else - Actions
      • -------- ================================================ --------
      • Custom script: set udg_BoL_Point[1] = null
      • Custom script: set udg_BoL_Point[2] = null
 
Level 37
Joined
Jul 22, 2015
Messages
3,485
Hey guys, just wanted to give some critique on your triggers.

For Skyflash:
  • You are turning the loop on in both places on cast
  • I don't see the need of indexing Damage_Amount, Speed, and Damage_Range
  • (Matching unit) is not the best way of filtering out your unit groups. Take a look at how BloodDrunk does it. His way makes it so that it is a lot easier to read, and less of a pain to add and or remove filters
  • You should store (Picked unit) into a variable
  • I don't see you deindexing the variables you indexed on cast. Try casting this spell with multiple units and check if it still works properly
  • You should check to turn off the trigger after you decrement Index_Size and Loop_Int
  • There are more things that can be done to slightly improve the performance, but that would just be me being too nitpicky xP

For BloodDrunk:
  • I don't see the purpose of storing the damage into an array when you can easily just call Damage[Ability Level[Index]] whenever you need to deal damage
  • Point[1] and PointDistance[] are storing the same locations. Why not just use one of them?
  • You don't have to null the locations or units
  • You should check to turn off the trigger after you decrement MaxIndex and Loop
  • What's the point of creating Point[2] before the Unit group loop if you're checking for the area around Point[1]?
  • You should add a magic immune filter to your unit group
  • (Owner of unit) should be indexed and stored into a variable
 
Level 5
Joined
Mar 6, 2015
Messages
130
Hey guys, just wanted to give some critique on your triggers.

For Skyflash:
  • You are turning the loop on in both places on cast
  • I don't see the need of indexing Damage_Amount, Speed, and Damage_Range
  • (Matching unit) is not the best way of filtering out your unit groups. Take a look at how BloodDrunk does it. His way makes it so that it is a lot easier to read, and less of a pain to add and or remove filters
  • You should store (Picked unit) into a variable
  • I don't see you deindexing the variables you indexed on cast. Try casting this spell with multiple units and check if it still works properly
  • You should check to turn off the trigger after you decrement Index_Size and Loop_Int
  • There are more things that can be done to slightly improve the performance, but that would just be me being too nitpicky xP

Well i see this spell has a lot of coding problems but my purpose of creating this was merely to show the method i used for this spell to get a proper answer .well i made it in 10 minutes and deleted it after i got the answer :) but thanks to spend time for reading them and give advise :)
 
Status
Not open for further replies.
Top