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

Demon Spinning v1.03

This is my best production for the moment.

This spell is very customizable and with some modifications, you can do some very well others spells with just the same base princip.

The spell is totally MUI, leakless (i think) and without bugs (i don't guarantee it 100% free bug, since minors bugs are also possible on every spell).

Spell Description :

The hero starts channeling powerful demon's spirits, creating circles of malefic power around him. Those circles turn around themselves, dealing damages to enemies on their path and regenerating the Hero for 50% of the infliged damages.

level 1 - 2circles, 50damages per ball, last 20 secondes.
level 2 - 4circles, 75damages per ball, last 25 secondes.
level 3 - 6circles, 100damages per ball, last 30 secondes.

The Triggers :


  • DS Init
    • Events
      • Map initialization
    • Conditions
    • Actions
      • -------- Each Array of this Variable set the number of Circles for a specific Level. --------
      • -------- Chaque Déploiement de cette Variable détermine le nombre de Cercles pour un Niveau spécifique. --------
      • Set DS_NumberOfCircle[1] = 2
      • Set DS_NumberOfCircle[2] = 4
      • Set DS_NumberOfCircle[3] = 6
      • -------- Each Array of this Variable set the Area of Effect for each Circle. --------
      • -------- Chaque Déploiement de cette Variable détermine la Zone d'Effet de chaque Cercle. --------
      • Set DS_CircleAoe[1] = 200.00
      • Set DS_CircleAoe[2] = 230.00
      • Set DS_CircleAoe[3] = 260.00
      • Set DS_CircleAoe[4] = 290.00
      • Set DS_CircleAoe[5] = 320.00
      • Set DS_CircleAoe[6] = 350.00
      • -------- Each Array of this Variable set the Circle's Direction and the Angle Interval between each Ball of each Circle. --------
      • -------- Chaque Déploiement de cette Variable détermine la Direction du cercle et l'Angle d'Intervalle entre chaque Boule de chaque Cercle. --------
      • -------- Set it to a Positive value for turning from North to East and to a Negative value for turning from North to West. --------
      • -------- Mettez le Ã* une valeur Positive pour que le cercle tourne dans le sens des Aiguilles d'une Montre et Ã* une valeur Négative pour que le cercle tourne dans le sens Inverse des Aiguilles d'une Montre. --------
      • Set DS_CircleDirectionAndSpeed[1] = 25.00
      • Set DS_CircleDirectionAndSpeed[2] = -25.00
      • Set DS_CircleDirectionAndSpeed[3] = 25.00
      • Set DS_CircleDirectionAndSpeed[4] = -25.00
      • Set DS_CircleDirectionAndSpeed[5] = 25.00
      • Set DS_CircleDirectionAndSpeed[6] = -25.00
      • -------- Each Array of this Variable set the Start Angle of each Circle. --------
      • -------- Chaque Déploiement de cette Variable définis l'Angle de Départ de chaque Cercle. --------
      • -------- 0.00 (or 360.00) is equal to the Facing of the Caster Unit. --------
      • -------- 0.00 (ou 360.00) est égal Ã* l'Angle de l'Unité Déclencheuse. --------
      • Set DS_CircleStartAngle[1] = 0.00
      • Set DS_CircleStartAngle[2] = 0.00
      • Set DS_CircleStartAngle[3] = 120.00
      • Set DS_CircleStartAngle[4] = 240.00
      • Set DS_CircleStartAngle[5] = 240.00
      • Set DS_CircleStartAngle[6] = 120.00
      • -------- Each Array of this Variable set the Damages deals by each Ball for each Level. --------
      • -------- Chaque Déploiement de cette Variable détermine les Dommages infligés par chaque Boule pour chaque Niveau. --------
      • Set DS_BallDamages[1] = 50.00
      • Set DS_BallDamages[2] = 75.00
      • Set DS_BallDamages[3] = 100.00
      • -------- Each Array of this Variable set the Life stolen by each Ball for each Level. This don't add damages ! --------
      • -------- Chaque Déploiement de cette Variable détermine la Vie volée par chaque Boule pour chaque Niveau. Cela ne rajoute pas de Dommages ! --------
      • Set DS_BallLifeSteal[1] = 25.00
      • Set DS_BallLifeSteal[2] = 37.50
      • Set DS_BallLifeSteal[3] = 50.00
      • -------- Each Array of this Variable set the Area of Effect of the Damages deals by each Ball for each Level --------
      • -------- Chaque Déploiement de cette Variable détermine la Zone d'Effet des Dommages infligés par chaque Boule pour chaque Niveau. --------
      • Set DS_BallDamagesAoe[1] = 80.00
      • Set DS_BallDamagesAoe[2] = 80.00
      • Set DS_BallDamagesAoe[3] = 80.00
      • -------- Those Variables set the Type of Damage inflicted by the Balls. --------
      • -------- Ces Variables déterminent le Type de Dommages infligés par les boules. --------
      • Set DS_BallDamagesType = Chaos
      • Set DS_BallDamagesTypes2 = Universal
      • -------- Each Array of this Variable set the Height Increase for each Ball for each CIrcle --------
      • -------- Chaque Déploiement de cette Variable détermine l'Incrémentation de Hauteur pour chaque boule de chaque Cercle. --------
      • Set DS_BallHeightIncrease[1] = 5.00
      • Set DS_BallHeightIncrease[2] = 5.00
      • Set DS_BallHeightIncrease[3] = 5.00
      • Set DS_BallHeightIncrease[4] = 5.00
      • Set DS_BallHeightIncrease[5] = 5.00
      • Set DS_BallHeightIncrease[6] = 5.00
      • -------- Each Array of this Variable set the Speed and the Direction of each Ball for each Circle. --------
      • -------- Chaque Déploiement de cette Variable détermine la Vitesse et la Direction des Boules pour chaque Cercle. --------
      • -------- Set it to a Positive value for turning from North to East and to a Negative value for turning from North to West. --------
      • -------- Mettez le Ã* une valeur Positive pour que le cercle tourne dans le sens des Aiguilles d'une Montre et Ã* une valeur Négative pour que le cercle tourne dans le sens Inverse des Aiguilles d'une Montre. --------
      • Set DS_BallDirectionAndSpeed[1] = 5.00
      • Set DS_BallDirectionAndSpeed[2] = -5.00
      • Set DS_BallDirectionAndSpeed[3] = 5.00
      • Set DS_BallDirectionAndSpeed[4] = -5.00
      • Set DS_BallDirectionAndSpeed[5] = 5.00
      • Set DS_BallDirectionAndSpeed[6] = -5.00
      • -------- Each Array of this Variable set the Creation Interval of the balls for each Levels. --------
      • -------- Chaque Déploiement de cette Variable définis l'Intervalle de Création des Boules pour chaque Niveau. --------
      • Set DS_BallCreationInterval[1] = 5
      • Set DS_BallCreationInterval[2] = 5
      • Set DS_BallCreationInterval[3] = 5
      • -------- Each Array of this Variable set the Life Time of each Ball for each Circle. --------
      • -------- Chaque Déploiement de cette Variable définis la Durée de Vie de chaque boule pour chaque Cercle. --------
      • Set DS_BallLiveTime[1] = 5.50
      • Set DS_BallLiveTime[2] = 5.50
      • Set DS_BallLiveTime[3] = 5.50
      • Set DS_BallLiveTime[4] = 5.50
      • Set DS_BallLiveTime[5] = 5.50
      • Set DS_BallLiveTime[6] = 5.50
      • -------- Each Array of this Variable set the Duration of the Spell for a specific Level. --------
      • -------- Chaque Déploiement de cette Variable définis la Durée du Sort pour un Niveau Spécifique. --------
      • Set DS_Duration[1] = 20.00
      • Set DS_Duration[2] = 25.00
      • Set DS_Duration[3] = 30.00
      • -------- This is the special effect at Ball Spawn. --------
      • -------- L'effet spécial lors du Spawn d'une Boule. --------
      • Set DS_Effect = Abilities\Spells\Human\Feedback\ArcaneTowerAttack.mdl
      • -------- Create and Store Hashtable --------
      • -------- Crée et Store une Hashtable --------
      • Hashtable - Create a hashtable
      • Set DS_Hashtable = (Last created hashtable)
  • DS Cast
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Demon Spinning
    • Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (DS_CastersGroup is empty) Equal to True
          • (DS_BallsGroup is empty) Equal to True
        • Then - Actions
          • Trigger - Turn on DS Loop <gen>
          • Trigger - Turn on DS End <gen>
          • Trigger - Turn on DS UDie <gen>
        • Else - Actions
      • Set DS_TempUnit = (Triggering unit)
      • Custom script: set udg_DS_TempInteger = GetHandleId(udg_DS_TempUnit)
      • Unit Group - Add DS_Tempunit to DS_CastersGroup
      • Hashtable - Save DS_Duration[(Level of Demon Spinning for (Triggering unit))] as 0 of DS_TempInteger in DS_Hashtable
      • Hashtable - Save 0.00 as 1 of DS_TempInteger in DS_Hashtable
      • Hashtable - Save 0 as 2 of DS_TempInteger in DS_Hashtable
      • Hashtable - Save (Level of Demon Spinning for DS_TempUnit) as 3 of DS_TempInteger in DS_Hashtable
  • DS Loop
    • Events
      • Time - Every 0.04 seconds of game time
    • Conditions
    • Actions
      • Unit Group - Pick every unit in DS_CastersGroup and do (Actions)
        • Loop - Actions
          • Set DS_TempUnit = (Picked unit)
          • Custom script: set udg_DS_TempInteger = GetHandleId(udg_DS_TempUnit)
          • Set DS_TempInteger2 = (Load 3 of DS_TempInteger from DS_Hashtable)
          • Hashtable - Save ((Load 0 of DS_TempInteger from DS_Hashtable) - 0.04) as 0 of DS_TempInteger in DS_Hashtable
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (Load 0 of DS_TempInteger from DS_Hashtable) Less than or equal to 0.00
            • Then - Actions
              • Unit Group - Remove DS_TempUnit from DS_CastersGroup
              • Custom script: call FlushChildHashtable(udg_DS_Hashtable, udg_DS_TempInteger)
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • (DS_CastersGroup is empty) Equal to True
                  • (DS_BallsGroup is empty) Equal to True
                • Then - Actions
                  • Trigger - Turn off DS End <gen>
                  • Trigger - Turn off DS UDie <gen>
                  • Trigger - Turn off (This trigger)
                • Else - Actions
            • Else - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (Load 2 of DS_TempInteger from DS_Hashtable) Greater than or equal to DS_BallCreationInterval[DS_TempInteger2]
            • Then - Actions
              • Hashtable - Save ((Load 1 of DS_TempInteger from DS_Hashtable) + 1.00) as 1 of DS_TempInteger in DS_Hashtable
              • Hashtable - Save 0 as 2 of DS_TempInteger in DS_Hashtable
              • Set DS_CasterLocation = (Position of DS_TempUnit)
              • For each (Integer A) from 1 to DS_NumberOfCircle[DS_TempInteger2], do (Actions)
                • Loop - Actions
                  • Set DS_BallLocation = (DS_CasterLocation offset by DS_CircleAoe[(Integer A)] towards (((Facing of DS_TempUnit) + DS_CircleStartAngle[(Integer A)]) + ((Load 1 of (Key (Picked Unit)) from DS_Hashtable) x DS_CircleDirectionAndSpeed[(Integer A)])) degrees)
                  • Unit - Create 1 DS Ball for (Owner of DS_TempUnit) at DS_BallLocation facing Default building facing degrees
                  • Set DS_TempUnit2 = (Last created unit)
                  • Custom script: set udg_DS_TempInteger = GetHandleId(udg_DS_TempUnit2)
                  • Hashtable - Save (Integer A) as 0 of DS_TempInteger in DS_Hashtable
                  • Hashtable - Save Handle OfDS_TempUnit as 1 of DS_TempInteger in DS_Hashtable
                  • Animation - Change DS_TempUnit2 flying height to 0.00 at 0.00
                  • Special Effect - Create a special effect at DS_BallLocation using DS_Effect
                  • Special Effect - Destroy (Last created special effect)
                  • Unit Group - Add DS_TempUnit2 to DS_BallsGroup
                  • Unit - Add a DS_BallLiveTime[(Integer A)] second Generic expiration timer to DS_TempUnit2
                  • Custom script: set bj_wantDestroyGroup = true
                  • Unit Group - Pick every unit in (Units within DS_BallDamagesAoe[DS_TempInteger2] of DS_BallLocation matching (((Matching unit) belongs to an enemy of (Owner of DS_TempUnit)) Equal to True)) and do (Actions)
                    • Loop - Actions
                      • Unit - Cause DS_TempUnit to damage (Picked unit), dealing DS_BallDamages[DS_TempInteger2] damage of attack type DS_BallDamageType and damage type DS_BallDamageType2
                      • Unit - Set life of DS_TempUnit to ((Life of DS_TempUnit) + DS_BallLifeSteal[DS_TempInteger2])
                  • Custom script: call RemoveLocation(udg_DS_BallLocation)
              • Custom script: call RemoveLocation(udg_DS_CasterLocation)
            • Else - Actions
              • Hashtable - Save ((Load 2 of DS_TempInteger from DS_Hashtable) + 1) as 2 of DS_TempInteger in DS_Hashtable
      • Unit Group - Pick every unit in DS_BallsGroup and do (Actions)
        • Loop - Actions
          • Set DS_TempUnit = (Picked unit)
          • Custom script: set udg_DS_TempInteger = GetHandleId(udg_DS_TempUnit)
          • Set DS_BallLocation = (Position of DS_TempUnit)
          • Set DS_CasterLocation = (Position of (Load 1 of DS_TempInteger in DS_Hashtable))
          • Set DS_BallLocationNew = (DS_CasterLocation offset by DS_CircleAoe[(Load 0 of DS_TempInteger from DS_Hashtable)] towards ((Angle from DS_CasterLocation to DS_BallLocation) + DS_BallDirectionAndSpeed[(Load 0 of DS_TempInteger from DS_Hashtable)]) degrees)
          • Set DS_TempReal = ((Current flying height of DS_TempUnit) + DS_BallHeightIncrease[(Load 0 of DS_TempInteger from DS_Hashtable)])
          • Unit - Move (Picked unit) instantly to DS_BallLocationNew, facing DS_BallLocation
          • Animation - Change DS_TempUnit flying height to DS_TempReal at 0.00
          • Custom script: call RemoveLocation(udg_DS_CasterLocation)
          • Custom script: call RemoveLocation(udg_DS_BallLocation)
          • Custom script: call RemoveLocation(udg_DS_BallLocationNew)
  • DS End
    • Events
      • Unit - A unit Die
      • Unit - A unit Is issued an order targeting an object
      • Unit - A unit Is issued an order targeting a point
      • Unit - A unit Is issued an order with no target
    • Conditions
      • ((Triggering unit) is in DS_CastersGroup) Equal to True
    • Actions
      • Set DS_TempUnit = (Triggering unit)
      • Unit Group - Remove DS_TempUnit from DS_CastersGroup
      • Custom script: call FlushChildHashtable(udg_DS_Hashtable, GetHandleId(udg_DS_TempUnit))
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (DS_CastersGroup is empty) Equal to True
          • (DS_BallsGroup is empty) Equal to True
        • Then - Actions
          • Trigger - Turn off DS Loop <gen>
          • Trigger - Turn off DS UDie <gen>
          • Trigger - Turn off (This trigger)
        • Else - Actions
  • DS UDie
    • Events
      • Unit - A unit Dies
    • Conditions
      • (Unit-type of (Triggering unit)) Equal to DS Ball
    • Actions
      • Set DS_TempUnit = (Triggering unit)
      • Custom script: call FlushChildHashtable(udg_DS_Hashtable, GetHandleId(udg_DS_TempUnit))
      • Unit Group - Remove DS_TempUnit from DS_BallsGroup
      • Unit - Remove DS_TempUnit from the game
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (DS_CastersGroup is empty) Equal to True
          • (DS_BallsGroup is empty) Equal to True
        • Then - Actions
          • Trigger - Turn off DS Loop <gen>
          • Trigger - Turn off DS End <gen>
          • Trigger - Turn off (This trigger)
        • Else - Actions


Video :


Changelog :

1.00 : Initial Release.
1.01 : Better coding, Added Variable for configure DamageType, Description Improved and EN Import Notice Improved.
1.02 : Added a Variable for configure Ball Duration and another Variable for configure Ball Creation Interval. Improved EN Import Notice.
1.03 : Level of Ability is now stored in Hashtable at the moment of the cast. DS_BallLiveTime is now set at 5.50 for all levels in Test Map to reduce a little the lags.

Keywords:
Shadow, Demon, Malefic, Channeling, GUI, MUI, Vladadamm, Demonic, Evil, Circle, Spin, Turn, Damages, Lifesteal.
Contents

Demon Spinning v1.03 (Map)

Reviews
Reviewed by Maker, Demon Spinning v1.03, 27th Dec Approved. The main reason for low rating is the FPS drop it causes. Try casting it with two units at the same time, both ahaving the ability at level 3. The effect is good, but the spell idea...

Moderator

M

Moderator

Reviewed by Maker, Demon Spinning v1.03, 27th Dec

Approved.

The main reason for low rating is the FPS drop it causes. Try casting it with two units at the same time, both ahaving the ability at level 3.

The effect is good, but the spell idea could be more original.

Suggestions for improvements
  • Make it support more than three levels properly
  • The spell creates hundreds of units per cast at level 3. That is quite much
  • The spell is performance heavy and can lag on some computers
  • Instead of DS_End trigger, you could check the current order of the caster in the looping trigger
  • Improve the English in your importing instructions. The instructions can be a bit confusing
  • Tooltip could benefit from slight improvements. Spelling, missing spaces and some non capital letters for example. Look at standard Blizzard tooltips
  • I'd use 0.03 seconds for the interval, 0.04 seconds looks choppy to me


Maker, Demon Spinning v1.01, 22nd Dec

Required changes to be approved
  • You should use level of ability at the time of casting
  • The spell goes on even after the caster is dead
  • The spell creates 744 units per cast at level 3. That is simply too much. Make the number of units and unit creation iterval configurable
  • The spell is performance heavy and can lag on some computers

Optional
  • Instead of DS_End trigger, you could check the current order of the caster in the looping trigger
  • Improve the English in your importing instructions. The instructions can be a bit confusing
  • Tooltip could benefit from slight improvements. Spelling, missing spaces and some non capital letters for example. Look at standard Blizzard tooltips
  • I'd use 0.03 seconds for the interval, 0.04 seconds looks choppy to me
 
Holy shit, I need to test this.

edit

The effects are wonderful, but the testmap isn't the best ;/
You should set the cooldown to 0 and give us multiple testers with 2^31-1 mana and hp :p

As for the triggers, here, I posted them for you in English:


  • DS Init
    • Events
      • Map initialization
    • Conditions
    • Actions
      • -------- Each Array of this Variable set the number of Circles for a specific Level. --------
      • -------- Chaque Déploiement de cette Variable détermine le nombre de Cercles pour un Niveau spécifique. --------
      • Set DS_NumberOfCircle[1] = 2
      • Set DS_NumberOfCircle[2] = 4
      • Set DS_NumberOfCircle[3] = 6
      • -------- Each Array of this Variable set the Area of Effect for each Circle. --------
      • -------- Chaque Déploiement de cette Variable détermine la Zone d'Effet de chaque Cercle. --------
      • Set DS_CircleAoe[1] = 200.00
      • Set DS_CircleAoe[2] = 230.00
      • Set DS_CircleAoe[3] = 260.00
      • Set DS_CircleAoe[4] = 290.00
      • Set DS_CircleAoe[5] = 320.00
      • Set DS_CircleAoe[6] = 350.00
      • -------- Each Array of this Variable set the Circle's Direction and the Angle Interval between each Ball of each Circle. --------
      • -------- Chaque Déploiement de cette Variable détermine la Direction du cercle et l'Angle d'Intervalle entre chaque Boule de chaque Cercle. --------
      • -------- Set it to a Positive value for turning from North to East and to a Negative value for turning from North to West. --------
      • -------- Mettez le Ã* une valeur Positive pour que le cercle tourne dans le sens des Aiguilles d'une Montre et Ã* une valeur Négative pour que le cercle tourne dans le sens Inverse des Aiguilles d'une Montre. --------
      • Set DS_CircleDirectionAndSpeed[1] = 25.00
      • Set DS_CircleDirectionAndSpeed[2] = -25.00
      • Set DS_CircleDirectionAndSpeed[3] = 25.00
      • Set DS_CircleDirectionAndSpeed[4] = -25.00
      • Set DS_CircleDirectionAndSpeed[5] = 25.00
      • Set DS_CircleDirectionAndSpeed[6] = -25.00
      • -------- Each Array of this Variable set the Start Angle of each Circle. --------
      • -------- Chaque Déploiement de cette Variable définis l'Angle de Départ de chaque Cercle. --------
      • -------- 0.00 (or 360.00) is equal to the Facing of the Caster Unit. --------
      • -------- 0.00 (ou 360.00) est égal Ã* l'Angle de l'Unité Déclencheuse. --------
      • Set DS_CircleStartAngle[1] = 0.00
      • Set DS_CircleStartAngle[2] = 0.00
      • Set DS_CircleStartAngle[3] = 120.00
      • Set DS_CircleStartAngle[4] = 240.00
      • Set DS_CircleStartAngle[5] = 240.00
      • Set DS_CircleStartAngle[6] = 120.00
      • -------- Each Array of this Variable set the Damages deals by each Ball for each Level. --------
      • -------- Chaque Déploiement de cette Variable détermine les Dommages infligés par chaque Boule pour chaque Niveau. --------
      • Set DS_BallDamages[1] = 50.00
      • Set DS_BallDamages[2] = 75.00
      • Set DS_BallDamages[3] = 100.00
      • -------- Each Array of this Variable set the Life stolen by each Ball for each Level. This don't add damages ! --------
      • -------- Chaque Déploiement de cette Variable détermine la Vie volée par chaque Boule pour chaque Niveau. Cela ne rajoute pas de Dommages ! --------
      • Set DS_BallLifeSteal[1] = 25.00
      • Set DS_BallLifeSteal[2] = 37.50
      • Set DS_BallLifeSteal[3] = 50.00
      • -------- Each Array of this Variable set the Area of Effect of the Damages deals by each Ball for each Level --------
      • -------- Chaque Déploiement de cette Variable détermine la Zone d'Effet des Dommages infligés par chaque Boule pour chaque Niveau. --------
      • Set DS_BallDamagesAoe[1] = 80.00
      • Set DS_BallDamagesAoe[2] = 80.00
      • Set DS_BallDamagesAoe[3] = 80.00
      • -------- Each Array of this Variable set the Height Increase for each Ball for each CIrcle --------
      • -------- Chaque Déploiement de cette Variable détermine l'Incrémentation de Hauteur pour chaque boule de chaque Cercle. --------
      • Set DS_BallHeightIncrease[1] = 5.00
      • Set DS_BallHeightIncrease[2] = 5.00
      • Set DS_BallHeightIncrease[3] = 5.00
      • Set DS_BallHeightIncrease[4] = 5.00
      • Set DS_BallHeightIncrease[5] = 5.00
      • Set DS_BallHeightIncrease[6] = 5.00
      • -------- Each Array of this Variable set the Speed and the Direction of each Ball for each Circle. --------
      • -------- Chaque Déploiement de cette Variable détermine la Vitesse et la Direction des Boules pour chaque Cercle. --------
      • -------- Set it to a Positive value for turning from North to East and to a Negative value for turning from North to West. --------
      • -------- Mettez le Ã* une valeur Positive pour que le cercle tourne dans le sens des Aiguilles d'une Montre et Ã* une valeur Négative pour que le cercle tourne dans le sens Inverse des Aiguilles d'une Montre. --------
      • Set DS_BallDirectionAndSpeed[1] = 5.00
      • Set DS_BallDirectionAndSpeed[2] = -5.00
      • Set DS_BallDirectionAndSpeed[3] = 5.00
      • Set DS_BallDirectionAndSpeed[4] = -5.00
      • Set DS_BallDirectionAndSpeed[5] = 5.00
      • Set DS_BallDirectionAndSpeed[6] = -5.00
      • -------- Each Array of this Variable set the Duration of the Spell for a specific Level. --------
      • -------- Chaque Déploiement de cette Variable définis la Durée du Sort pour un Niveau Spécifique. --------
      • Set DS_Duration[1] = 20.00
      • Set DS_Duration[2] = 25.00
      • Set DS_Duration[3] = 30.00
      • -------- This is the special effect at Ball Spawn. --------
      • -------- L'effet spécial lors du Spawn d'une Boule. --------
      • Set DS_Effect = Abilities\Spells\Human\Feedback\ArcaneTowerAttack.mdl
      • -------- Create and Store Hashtable --------
      • -------- Crée et Store une Hashtable --------
      • Hashtable - Create a hashtable
      • Set DS_Hashtable = (Last created hashtable)
  • DS Cast
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Demon Spinning
    • Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (DS_CastersGroup is empty) Equal to True
          • (DS_BallsGroup is empty) Equal to True
        • Then - Actions
          • Trigger - Turn on DS Loop <gen>
          • Trigger - Turn on DS End <gen>
          • Trigger - Turn on DS UDie <gen>
        • Else - Actions
      • Unit Group - Add (Triggering unit) to DS_CastersGroup
      • Hashtable - Save DS_Duration[(Level of Demon Spinning for (Triggering unit))] as 0 of (Key (Triggering unit)) in DS_Hashtable
      • Hashtable - Save 0.00 as 1 of (Key (Triggering unit)) in DS_Hashtable
      • Hashtable - Save 0 as 2 of (Key (Triggering unit)) in DS_Hashtable
  • DS Loop
    • Events
      • Time - Every 0.04 seconds of game time
    • Conditions
    • Actions
      • Unit Group - Pick every unit in DS_CastersGroup and do (Actions)
        • Loop - Actions
          • Set DS_TempUnit = (Picked unit)
          • Hashtable - Save ((Load 0 of (Key (Picked unit)) from DS_Hashtable) - 0.04) as 0 of (Key (Picked unit)) in DS_Hashtable
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (Load 0 of (Key (Picked unit)) from DS_Hashtable) Less than or equal to 0.00
            • Then - Actions
              • Unit Group - Remove DS_TempUnit from DS_CastersGroup
              • Hashtable - Clear all child hashtables of child (Key (Picked unit)) in DS_Hashtable
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • (DS_CastersGroup is empty) Equal to True
                  • (DS_BallsGroup is empty) Equal to True
                • Then - Actions
                  • Trigger - Turn off DS End <gen>
                  • Trigger - Turn off DS UDie <gen>
                  • Trigger - Turn off (This trigger)
                • Else - Actions
            • Else - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (Load 2 of (Key (Picked unit)) from DS_Hashtable) Greater than or equal to 5
            • Then - Actions
              • Hashtable - Save ((Load 1 of (Key (Picked unit)) from DS_Hashtable) + 1.00) as 1 of (Key (Picked unit)) in DS_Hashtable
              • Hashtable - Save 0 as 2 of (Key (Picked unit)) in DS_Hashtable
              • Set DS_CasterLocation = (Position of DS_TempUnit)
              • For each (Integer A) from 1 to DS_NumberOfCircle[(Level of Demon Spinning for DS_TempUnit)], do (Actions)
                • Loop - Actions
                  • Set DS_BallLocation = (DS_CasterLocation offset by DS_CircleAoe[(Integer A)] towards (((Facing of DS_TempUnit) + DS_CircleStartAngle[(Integer A)]) + ((Load 1 of (Key (Picked unit)) from DS_Hashtable) x DS_CircleDirectionAndSpeed[(Integer A)])) degrees)
                  • Unit - Create 1 DS Ball for (Owner of DS_TempUnit) at DS_BallLocation facing Default building facing degrees
                  • Hashtable - Save (Integer A) as 0 of (Key (Last created unit)) in DS_Hashtable
                  • Hashtable - Save Handle OfDS_TempUnit as 1 of (Key (Last created unit)) in DS_Hashtable
                  • Animation - Change (Last created unit) flying height to 0.00 at 1000000.00
                  • Special Effect - Create a special effect at DS_BallLocation using DS_Effect
                  • Special Effect - Destroy (Last created special effect)
                  • Unit Group - Add (Last created unit) to DS_BallsGroup
                  • Unit - Add a 6.00 second Generic expiration timer to (Last created unit)
                  • Custom script: set bj_wantDestroyGroup = true
                  • Unit Group - Pick every unit in (Units within DS_BallDamagesAoe[(Level of Demon Spinning for DS_TempUnit)] of DS_BallLocation matching (((Matching unit) belongs to an enemy of (Owner of DS_TempUnit)) Equal to True)) and do (Actions)
                    • Loop - Actions
                      • Unit - Cause DS_TempUnit to damage (Picked unit), dealing DS_BallDamages[(Level of Demon Spinning for DS_TempUnit)] damage of attack type Chaos and damage type Universal
                      • Unit - Set life of DS_TempUnit to ((Life of DS_TempUnit) + DS_BallLifeSteal[(Level of Demon Spinning for DS_TempUnit)])
                  • Custom script: call RemoveLocation(udg_DS_BallLocation)
              • Custom script: call RemoveLocation(udg_DS_CasterLocation)
            • Else - Actions
              • Hashtable - Save ((Load 2 of (Key (Picked unit)) from DS_Hashtable) + 1) as 2 of (Key (Picked unit)) in DS_Hashtable
      • Unit Group - Pick every unit in DS_BallsGroup and do (Actions)
        • Loop - Actions
          • Set DS_BallLocation = (Position of (Picked unit))
          • Set DS_CasterLocation = (Position of (Load 1 of (Key (Picked unit)) in DS_Hashtable))
          • Set DS_BallLocationNew = (DS_CasterLocation offset by DS_CircleAoe[(Load 0 of (Key (Picked unit)) from DS_Hashtable)] towards ((Angle from DS_CasterLocation to DS_BallLocation) + DS_BallDirectionAndSpeed[(Load 0 of (Key (Picked unit)) from DS_Hashtable)]) degrees)
          • Set DS_TempReal = ((Current flying height of (Picked unit)) + DS_BallHeightIncrease[(Load 0 of (Key (Picked unit)) from DS_Hashtable)])
          • Unit - Move (Picked unit) instantly to DS_BallLocationNew, facing DS_BallLocation
          • Animation - Change (Picked unit) flying height to DS_TempReal at 10000000.00
          • Custom script: call RemoveLocation(udg_DS_CasterLocation)
          • Custom script: call RemoveLocation(udg_DS_BallLocation)
          • Custom script: call RemoveLocation(udg_DS_BallLocationNew)
  • DS End
    • Events
      • Unit - A unit Is issued an order targeting an object
      • Unit - A unit Is issued an order targeting a point
      • Unit - A unit Is issued an order with no target
    • Conditions
      • ((Triggering unit) is in DS_CastersGroup) Equal to True
    • Actions
      • Unit Group - Remove (Triggering unit) from DS_CastersGroup
      • Hashtable - Clear all child hashtables of child (Key (Triggering unit)) in DS_Hashtable
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (DS_CastersGroup is empty) Equal to True
          • (DS_BallsGroup is empty) Equal to True
        • Then - Actions
          • Trigger - Turn off DS Loop <gen>
          • Trigger - Turn off DS UDie <gen>
          • Trigger - Turn off (This trigger)
        • Else - Actions
  • DS UDie
    • Events
      • Unit - A unit Dies
    • Conditions
      • (Unit-type of (Triggering unit)) Equal to DS Ball
    • Actions
      • Hashtable - Clear all child hashtables of child (Key (Triggering unit)) in DS_Hashtable
      • Unit Group - Remove (Triggering unit) from DS_BallsGroup
      • Unit - Remove (Triggering unit) from the game
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (DS_CastersGroup is empty) Equal to True
          • (DS_BallsGroup is empty) Equal to True
        • Then - Actions
          • Trigger - Turn off DS Loop <gen>
          • Trigger - Turn off DS End <gen>
          • Trigger - Turn off (This trigger)
        • Else - Actions


Now, let's move on to optimizations shall we? :>

edit

For DS Cast:
- Cache (Triggering unit) into a unit variable (TempUnit)
- Cache Key(TempUnit) into an integer variable: Custom script: set udg_TempInteger = GetHandleId(udg_TempUnit)

For DS Loop:
- Cache Key(Picked unit) -> Custom script: set udg_TempInteger = GetHandleId(udg_DS_TempUnit) and use TempInteger instead.
- Cache (Last created unit) and other functions into temporary variables
- You can use 0 as the rate for changing the flying height instead of using 1000000 because 0 makes it instant.
- Cache the level of the ability into a variable because you're referencing it hundreds of times in there (The Group enumerations repeat the enclosed code multiple times)

For DS End:
- Cache (Triggering unit) for efficiency and instead of using that "Clear all child .." line, use this custom script: call FlushChildHashtable(udg_DS_Hashtable, GetHandleId(udg_DS_TempUnit))
This way, you'd actually gain something from caching the triggering unit.

For DS UDie:
- Same as DS End, cache the triggering unit and instead of "Clear all child ..", use this: call FlushChildHashtable(udg_DS_Hashtable, GetHandleId(udg_DS_TempUnit))

[------------End of Optimizationfag talk------------]
Hope this helps :>
 
Last edited:
Level 7
Joined
Sep 2, 2011
Messages
350
Hello, I like this spell a lot. The effects is really cool. The coding is pretty clean at least. So, this is a job well done.

Rating: 4.5/5
The movement of the effects are awesome
Well, the effects doesn't do anything much
In my view, it lags when you channel too much of them.
The spell is special because of the effects nothing more
I like it.
 
Level 5
Joined
Jan 5, 2012
Messages
134
Fantastic Spell. +Rep. I wonder If I can change the Circle Effect. Good job Anyway :)

EDIT AFTER TEST:
HOLY CRAP THATS LAGGY AT LEVEL 2 + 3
 
Level 5
Joined
Jan 5, 2012
Messages
134
Oh okay. You know. This is a Great Spell. With all the Evil looking sperms (Jokes) But you should perfect it with reduce of lag. Because I open it and tried level 1: Worked Fine. Level 2: Holy Burn! Alt + F4. So if you fix that. I will 5/5 And Rep you.
 
Level 6
Joined
Aug 5, 2015
Messages
202
i use this spell in my map, i need reduce loop time to 0.08 or 0.1 sec to reduce lag
but the 1st time i cast this spell in my map the 1st 20 seconds will be lag
after that not lag anymore no matter how many times i cast this spell
why is that?

this is unperfect spell btw since the lag is the problem
 
Top