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

Tether v1.03

Tether


Note:
The Screenshot is not updated because Tether and Break Tether is now interchanging therefore only one command card slot is used by this spell.

Spell Info:
Tethers caster to an allied unit, granting bonus movement speed to both. When caster restores health or mana, tethered units target gain 1.0/1.25/1.5 x the amount. Any enemy unit that crosses the tether is slowed and damaged. The tether breaks when the allied unit moves too far away, or caster cancels the tether.
Mostly based on Dota 2 Io's Tether but without the Tree destroying and with Damage.


CONFIGURABLES
- Spell Duration
- Spell Damage
- Distance to the link for enemy units to get damaged
- Slow Duration
- Tethered Regeneration Gain Percentage
- Tether Maximum distance
- Tether distance for caster to Latch to target
- Distance to target when will the caster stop latching
- Latching Speed


  • Tether Configurables
    • Events
      • Map initialization
    • Conditions
    • Actions
      • -------- Define the abilities involved --------
      • Set Te_AbCode = Tether
      • Set TeBr_AbCode = Break Tether
      • Set TeS_AbCode = Tether Slow (Tornado)
      • Set TeS_BuffCode = Tether Slow (Slow Aura)
      • Set TeSpd_AbCode = Tether MS Gain (Tornado)
      • Set TeSpd_BuffCode = Tether Bonus
      • Set Te_AbConvert = Tether Convert
      • Set Te_AttackType = Spells
      • Set Te_DamageType = Magic
      • -------- Define how much distance enemy units are from the line to be caught --------
      • Set Te_LineDist = 50.00
      • -------- Define Visual Effects --------
      • Set Te_LightningType = Chain Lightning - Primary
      • Set Te_LightningTypeBreaking = Finger of Death
      • -------- The Special Effect attached to the Tethered Unit --------
      • Set Te_AttachTargetSFX = Abilities\Spells\Orc\LightningShield\LightningShieldTarget.mdl
      • -------- The Special Effect attached to the Tethered Unit --------
      • Set Te_AttachCasterSFX = Abilities\Spells\Undead\UnholyFrenzy\UnholyFrenzyTarget.mdl
      • -------- Define how much distance the latching unit moves every 0.03 second --------
      • Set Te_LatchSpeed = 30.00
      • -------- Define how long the duration last each level --------
      • Set Te_Duration[1] = 8.00
      • Set Te_Duration[2] = 11.00
      • Set Te_Duration[3] = 14.00
      • -------- Define the damage taken by units caught by the line --------
      • Set Te_Damage[1] = 150.00
      • Set Te_Damage[2] = 200.00
      • Set Te_Damage[3] = 250.00
      • -------- Define the Slow duration on enemy units caught within the link --------
      • Set Te_Slow_Duration[1] = 1.00
      • Set Te_Slow_Duration[2] = 1.50
      • Set Te_Slow_Duration[3] = 2.00
      • -------- When Caster restores health or mana, tethered units gain TargetGain x the amount --------
      • Set Te_TargetGain[1] = 1.00
      • Set Te_TargetGain[2] = 1.25
      • Set Te_TargetGain[3] = 1.50
      • -------- Tether will break if the distance between Caster and Target is greater than Te_BreakDist --------
      • Set Te_BreakDist[1] = 800.00
      • Set Te_BreakDist[2] = 1000.00
      • Set Te_BreakDist[3] = 1200.00
      • -------- The Distance when the Link will change visual effect to tell the player that Tether is about to Break because of too much distance --------
      • Set Te_AboutToBreakDist[1] = 600.00
      • Set Te_AboutToBreakDist[2] = 800.00
      • Set Te_AboutToBreakDist[3] = 1000.00
      • -------- If the Target is more than Te_LatchDistance units away, Caster will Latch into the unit --------
      • Set Te_LatchDistance[1] = 700.00
      • Set Te_LatchDistance[2] = 600.00
      • Set Te_LatchDistance[3] = 500.00
      • -------- When the Caster Latches, how close will it latch to the target --------
      • Set Te_LatchStopDist = 300.00
      • -------- End Configurables --------
      • Custom script: call DestroyGroup(udg_Te_AffectedUnits[0])
      • Custom script: call DestroyGroup(udg_Te_AffectedUnits[1])
      • Player Group - Pick every player in (All players) and do (Actions)
        • Loop - Actions
          • Player - Disable Te_AbConvert for (Picked player)
SPELL TRIGGERS:
  • Tether Cast
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Te_AbCode
    • Actions
      • -------- ----------------------------------------------------------------------------------------- --------
      • -------- ----------------------------------- Indexing ------------------------------------- --------
      • -------- ----------------------------------------------------------------------------------------- --------
      • Set Te_MaxIndex = (Te_MaxIndex + 1)
      • -------- ----------------------------------------------------------------------------------------- --------
      • -------- ---------------------------------- Spell Data ------------------------------------ --------
      • -------- ----------------------------------------------------------------------------------------- --------
      • Set Te_Caster[Te_MaxIndex] = (Triggering unit)
      • Set Te_Target[Te_MaxIndex] = (Target unit of ability being cast)
      • Set Te_CasterHP[Te_MaxIndex] = (Life of Te_Caster[Te_MaxIndex])
      • Set Te_CasterMana[Te_MaxIndex] = (Mana of Te_Caster[Te_MaxIndex])
      • Set Te_Owner[Te_MaxIndex] = (Triggering player)
      • -------- Stores affected enemy units into this group --------
      • Custom script: set udg_Te_AffectedUnits[udg_Te_MaxIndex] = CreateGroup()
      • Set Te_IndexedLevel[Te_MaxIndex] = (Level of Te_AbCode for Te_Caster[Te_MaxIndex])
      • -------- A non-array integer Te_Level is used for easier readability --------
      • Set Te_Level = Te_IndexedLevel[Te_MaxIndex]
      • -------- Replace Tether Ability with Brek Tether ability --------
      • Unit - Add Te_AbConvert to Te_Caster[Te_MaxIndex]
      • Unit - Add TeBr_AbCode to Te_Caster[Te_MaxIndex]
      • -------- ----------------------------------------------------------------------------------------- --------
      • -------- --------------------------------- Bonus Speed -------------------------------- --------
      • -------- ----------------------------------------------------------------------------------------- --------
      • Unit - Add TeSpd_AbCode to Te_Caster[Te_MaxIndex]
      • Unit - Set level of TeSpd_AbCode for Te_Caster[Te_MaxIndex] to Te_Level
      • Unit - Add TeSpd_AbCode to Te_Target[Te_MaxIndex]
      • Unit - Set level of TeSpd_AbCode for Te_Target[Te_MaxIndex] to Te_Level
      • -------- ----------------------------------------------------------------------------------------- --------
      • -------- ---------------------------------- Spell Timing --------------------------------- --------
      • -------- ----------------------------------------------------------------------------------------- --------
      • Set Te_TimeElapsed[Te_MaxIndex] = Te_Duration[Te_Level]
      • -------- ----------------------------------------------------------------------------------------- --------
      • -------- ---------------------------- Spell Visual Effects --------------------------- --------
      • -------- ----------------------------------------------------------------------------------------- --------
      • Set Te_TempLoc1 = (Position of Te_Caster[Te_MaxIndex])
      • Set Te_TempLoc2 = (Position of Te_Target[Te_MaxIndex])
      • Set Te_TempReal = (Distance between Te_TempLoc1 and Te_TempLoc2)
      • Special Effect - Create a special effect attached to the origin of Te_Target[Te_MaxIndex] using Te_AttachTargetSFX
      • Set Te_SFXTarget[Te_MaxIndex] = (Last created special effect)
      • Special Effect - Create a special effect attached to the origin of Te_Caster[Te_MaxIndex] using Te_AttachCasterSFX
      • Set Te_SFXCaster[Te_MaxIndex] = (Last created special effect)
      • Lightning - Create a Te_LightningType lightning effect from source Te_TempLoc1 to target Te_TempLoc2
      • Set Te_LinkEffect[Te_MaxIndex] = (Last created lightning effect)
      • Set Te_AboutToBreak[Te_MaxIndex] = False
      • Custom script: call RemoveLocation(udg_Te_TempLoc1)
      • Custom script: call RemoveLocation(udg_Te_TempLoc2)
      • -------- ----------------------------------------------------------------------------------------- --------
      • -------- ----------------------- To latch or not to latch --------------------------- --------
      • -------- ----------------------------------------------------------------------------------------- --------
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • Te_TempReal Greater than or equal to Te_LatchDistance[Te_Level]
        • Then - Actions
          • Set Te_Latching[Te_MaxIndex] = True
        • Else - Actions
          • Set Te_Latching[Te_MaxIndex] = False
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • Te_MaxIndex Equal to 1
        • Then - Actions
          • Trigger - Turn on Tether Periodic <gen>
        • Else - Actions
  • Tether Break
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to TeBr_AbCode
    • Actions
      • Custom script: local integer i = 1
      • Custom script: local integer counter = 0
      • Custom script: local unit tempUnit
      • Set Te_TempUnit = (Triggering unit)
      • -------- I know it is O(n) but to my defense, it is in GUI --------
      • For each (Integer Te_LoopInt) from 1 to Te_MaxIndex, do (Actions)
        • Loop - Actions
          • -------- Find the Tether Breaker --------
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • Te_Caster[Te_LoopInt] Equal to Te_TempUnit
            • Then - Actions
              • -------- Destroy Handles --------
              • Lightning - Destroy Te_LinkEffect[Te_LoopInt]
              • Custom script: call DestroyGroup(udg_Te_AffectedUnits[udg_Te_LoopInt])
              • Special Effect - Destroy Te_SFXTarget[Te_LoopInt]
              • Special Effect - Destroy Te_SFXCaster[Te_LoopInt]
              • -------- Remove Bonus Speed --------
              • -------- Count how many times Te_Target is Tethered --------
              • Custom script: set tempUnit = udg_Te_Target[udg_Te_LoopInt]
              • Custom script: loop
              • Custom script: exitwhen i > udg_Te_MaxIndex
              • Custom script: if tempUnit == udg_Te_Target[i] then
              • Custom script: set counter = counter + 1
              • Custom script: endif
              • Custom script: set i = i + 1
              • Custom script: endloop
              • Custom script: set tempUnit = null
              • Custom script: if counter == 1 then
              • Unit - Remove TeSpd_AbCode from Te_Target[Te_LoopInt]
              • Unit - Remove TeSpd_BuffCode buff from Te_Target[Te_LoopInt]
              • Custom script: endif
              • Unit - Remove TeSpd_AbCode from Te_Caster[Te_LoopInt]
              • Unit - Remove TeSpd_BuffCode buff from Te_Caster[Te_LoopInt]
              • Unit - Remove Te_AbConvert from Te_Caster[Te_LoopInt]
              • Unit - Remove TeBr_AbCode from Te_Caster[Te_LoopInt]
              • -------- Transfer Data --------
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • Te_LoopInt Not equal to Te_MaxIndex
                • Then - Actions
                  • Set Te_Caster[Te_LoopInt] = Te_Caster[Te_MaxIndex]
                  • Set Te_Target[Te_LoopInt] = Te_Target[Te_MaxIndex]
                  • Set Te_CasterHP[Te_LoopInt] = Te_CasterHP[Te_MaxIndex]
                  • Set Te_Latching[Te_LoopInt] = Te_Latching[Te_MaxIndex]
                  • Set Te_CasterMana[Te_LoopInt] = Te_CasterMana[Te_MaxIndex]
                  • Set Te_AffectedUnits[Te_LoopInt] = Te_AffectedUnits[Te_MaxIndex]
                  • Set Te_LinkEffect[Te_LoopInt] = Te_LinkEffect[Te_MaxIndex]
                  • Set Te_TimeLeft[Te_LoopInt] = Te_TimeLeft[Te_MaxIndex]
                  • Set Te_SFXTarget[Te_LoopInt] = Te_SFXTarget[Te_MaxIndex]
                  • Set Te_SFXCaster[Te_LoopInt] = Te_SFXCaster[Te_MaxIndex]
                  • Set Te_IndexedLevel[Te_LoopInt] = Te_IndexedLevel[Te_MaxIndex]
                  • Set Te_AboutToBreak[Te_LoopInt] = Te_AboutToBreak[Te_MaxIndex]
                  • Set Te_Owner[Te_LoopInt] = Te_Owner[Te_MaxIndex]
                • Else - Actions
              • -------- De-indexing --------
              • Set Te_MaxIndex = (Te_MaxIndex - 1)
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • Te_MaxIndex Equal to 0
                • Then - Actions
                  • Trigger - Turn off Tether Periodic <gen>
                • Else - Actions
              • Custom script: exitwhen true
            • Else - Actions

  • Tether Periodic
    • Events
      • Time - Every 0.03 seconds of game time
    • Conditions
    • Actions
      • Custom script: local integer i
      • Custom script: local integer counter
      • Custom script: local unit tempUnit
      • For each (Integer Te_LoopInt) from 1 to Te_MaxIndex, do (Actions)
        • Loop - Actions
          • -------- ----------------------------------------------------------------------------------------- --------
          • -------- ---------------------------------- Spell Timing --------------------------------- --------
          • -------- ----------------------------------------------------------------------------------------- --------
          • Set Te_TimeLeft[Te_LoopInt] = (Te_TimeLeft[Te_LoopInt] - 0.03)
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • Te_TimeLeft[Te_LoopInt] Greater than 0.00
              • (Te_Caster[Te_LoopInt] is dead) Equal to False
              • (Te_Target[Te_LoopInt] is dead) Equal to False
            • Then - Actions
              • -------- ---------------------------------------------------------------------------------------------- --------
              • -------- ----------------------- If Deindex Condition is FALSE --------------------- --------
              • -------- ---------------------------------------------------------------------------------------------- --------
              • -------- ----------------------------------------------------------------------------------------- --------
              • -------- ---------------------------- Spell Visual Effects --------------------------- --------
              • -------- ----------------------------------------------------------------------------------------- --------
              • Set Te_TempLoc1 = (Position of Te_Caster[Te_LoopInt])
              • Set Te_TempLoc2 = (Position of Te_Target[Te_LoopInt])
              • -------- A non-array integer Te_Level is used for easier readability --------
              • Set Te_Level = Te_IndexedLevel[Te_LoopInt]
              • -------- Move the Lightning Position --------
              • Custom script: call MoveLightningEx(udg_Te_LinkEffect[udg_Te_LoopInt], true, GetLocationX(udg_Te_TempLoc1), GetLocationY(udg_Te_TempLoc1), GetLocationZ(udg_Te_TempLoc1)+45, GetLocationX(udg_Te_TempLoc2), GetLocationY(udg_Te_TempLoc2), GetLocationZ(udg_Te_TempLoc2)+45)
              • -------- ----------------------------------------------------------------------------------------- --------
              • -------- ------------------------------------ Latching ------------------------------------ --------
              • -------- ----------------------------------------------------------------------------------------- --------
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • Te_Latching[Te_LoopInt] Equal to True
                • Then - Actions
                  • Unit - Turn collision for Te_Caster[Te_LoopInt] Off
                  • Set Te_TempReal = (Angle from Te_TempLoc1 to Te_TempLoc2)
                  • Set Te_TempLoc3 = (Te_TempLoc1 offset by Te_LatchSpeed towards Te_TempReal degrees)
                  • Unit - Move Te_Caster[Te_LoopInt] instantly to Te_TempLoc3
                  • Set Te_TempReal = (Distance between Te_TempLoc2 and Te_TempLoc3)
                  • Custom script: call RemoveLocation(udg_Te_TempLoc3)
                  • -------- Determine if latching is over --------
                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    • If - Conditions
                      • Te_TempReal Less than or equal to Te_LatchStopDist
                    • Then - Actions
                      • Set Te_Latching[Te_LoopInt] = False
                      • Unit - Turn collision for Te_Caster[Te_LoopInt] On
                    • Else - Actions
                • Else - Actions
                  • -------- Check whether to break tether or not --------
                  • Set Te_TempReal = (Distance between Te_TempLoc1 and Te_TempLoc2)
                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    • If - Conditions
                      • Te_TempReal Greater than or equal to Te_BreakDist[Te_Level]
                    • Then - Actions
                      • Set Te_TimeLeft[Te_LoopInt] = 0.00
                    • Else - Actions
                      • -------- Change Link Visual Effect --------
                      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                        • If - Conditions
                          • Te_AboutToBreak[Te_LoopInt] Equal to False
                          • Te_TempReal Greater than or equal to Te_AboutToBreakDist[Te_Level]
                        • Then - Actions
                          • Lightning - Destroy Te_LinkEffect[Te_LoopInt]
                          • Lightning - Create a Te_LightningTypeBreaking lightning effect from source Te_TempLoc1 to target Te_TempLoc2
                          • Set Te_LinkEffect[Te_LoopInt] = (Last created lightning effect)
                          • Set Te_AboutToBreak[Te_LoopInt] = True
                        • Else - Actions
                          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                            • If - Conditions
                              • Te_AboutToBreak[Te_LoopInt] Equal to True
                              • Te_TempReal Less than Te_AboutToBreakDist[Te_Level]
                            • Then - Actions
                              • Lightning - Destroy Te_LinkEffect[Te_LoopInt]
                              • Lightning - Create a Te_LightningType lightning effect from source Te_TempLoc1 to target Te_TempLoc2
                              • Set Te_LinkEffect[Te_LoopInt] = (Last created lightning effect)
                              • Set Te_AboutToBreak[Te_LoopInt] = False
                            • Else - Actions
              • -------- ----------------------------------------------------------------------------------------- --------
              • -------- ------------------- Check Enemies within the Line ------------------- --------
              • -------- ----------------------------------------------------------------------------------------- --------
              • -------- Get The Line Data --------
              • Set Te_X1 = (X of Te_TempLoc1)
              • Set Te_X2 = (X of Te_TempLoc2)
              • Set Te_Y1 = (Y of Te_TempLoc1)
              • Set Te_Y2 = (Y of Te_TempLoc2)
              • Set Te_TempReal = (Distance between Te_TempLoc1 and Te_TempLoc2)
              • -------- Ax+By+C=0 --------
              • Set Te_A = (Te_Y2 - Te_Y1)
              • Set Te_B = (Te_X1 - Te_X2)
              • Set Te_C = ((Te_X2 x Te_Y1) - (Te_Y2 x Te_X1))
              • -------- Midpoint of the line --------
              • Set Te_TempLoc3 = (Point(((Te_X1 + Te_X2) / 2.00), ((Te_Y1 + Te_Y2) / 2.00)))
              • Custom script: set bj_wantDestroyGroup = true
              • -------- Pick every units from mid point Te_TempLoc3 having a radius of LineLength/2 --------
              • -------- Condition: Non-Structure, Alive, Enemy --------
              • Unit Group - Pick every unit in (Units within (Te_TempReal / 2.00) of Te_TempLoc3 matching ((((Matching unit) is A structure) Equal to False) and ((((Matching unit) is alive) Equal to True) and (((Matching unit) belongs to an enemy of Te_Owner[Te_LoopInt]) Equal to True)))) and do (Actions)
                • Loop - Actions
                  • Set Te_TempUnit = (Picked unit)
                  • -------- Check if picked unit is already damaged --------
                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    • If - Conditions
                      • (Te_TempUnit is in Te_AffectedUnits[Te_LoopInt]) Equal to False
                    • Then - Actions
                      • -------- Get X and Y of Picked Unit --------
                      • Custom script: set udg_Te_X0 = GetUnitX(udg_Te_TempUnit)
                      • Custom script: set udg_Te_Y0 = GetUnitY(udg_Te_TempUnit)
                      • -------- If picked unit is close enough to the line --------
                      • -------- Distance between point and line = | Ax + By + C | / LineLength --------
                      • -------- Te_TempReal2 = Distance of Picked Unit to the Line --------
                      • Set Te_TempReal2 = ((Abs((((Te_A x Te_X0) + (Te_B x Te_Y0)) + Te_C))) / Te_TempReal)
                      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                        • If - Conditions
                          • Te_TempReal2 Less than or equal to Te_LineDist
                        • Then - Actions
                          • Unit Group - Add Te_TempUnit to Te_AffectedUnits[Te_LoopInt]
                          • -------- Damage --------
                          • Unit - Cause Te_Caster[Te_LoopInt] to damage Te_TempUnit, dealing Te_Damage[Te_Level] damage of attack type Te_AttackType and damage type Te_DamageType
                          • -------- Slow --------
                          • -------- Flow Control depending whether the unit already has slow or not --------
                          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                            • If - Conditions
                              • (Level of TeS_AbCode for Te_TempUnit) Equal to 0
                            • Then - Actions
                              • Unit - Add TeS_AbCode to Te_TempUnit
                              • Set TeS_MaxIndex = (TeS_MaxIndex + 1)
                              • Set TeS_Unit[TeS_MaxIndex] = Te_TempUnit
                              • Set TeS_TimeLeft[TeS_MaxIndex] = Te_Slow_Duration[Te_Level]
                              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                                • If - Conditions
                                  • TeS_MaxIndex Equal to 1
                                • Then - Actions
                                  • Trigger - Turn on Tether Slow Periodic <gen>
                                • Else - Actions
                            • Else - Actions
                              • -------- Find the TeS_LoopInt of the affected unit --------
                              • For each (Integer TeS_LoopInt) from 1 to Te_MaxIndex, do (Actions)
                                • Loop - Actions
                                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                                    • If - Conditions
                                      • Te_TempUnit Equal to TeS_Unit[TeS_LoopInt]
                                    • Then - Actions
                                      • Set TeS_TimeLeft[Te_LoopInt] = Te_Slow_Duration[Te_Level]
                                    • Else - Actions
                          • Unit - Set level of TeS_AbCode for Te_TempUnit to Te_Level
                        • Else - Actions
                    • Else - Actions
              • Custom script: call RemoveLocation(udg_Te_TempLoc1)
              • Custom script: call RemoveLocation(udg_Te_TempLoc2)
              • Custom script: call RemoveLocation(udg_Te_TempLoc3)
              • -------- ----------------------------------------------------------------------------------------- --------
              • -------- ------------------------- Regeneration Transfer -------------------------- --------
              • -------- ----------------------------------------------------------------------------------------- --------
              • Set Te_LifeIncrease = ((Life of Te_Caster[Te_LoopInt]) - Te_CasterHP[Te_LoopInt])
              • Set Te_ManaIncrease = ((Mana of Te_Caster[Te_LoopInt]) - Te_CasterMana[Te_LoopInt])
              • Set Te_CasterHP[Te_LoopInt] = (Life of Te_Caster[Te_LoopInt])
              • Set Te_CasterMana[Te_LoopInt] = (Mana of Te_Caster[Te_LoopInt])
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • Te_LifeIncrease Greater than 0.00
                • Then - Actions
                  • Unit - Set life of Te_Target[Te_LoopInt] to ((Life of Te_Target[Te_LoopInt]) + (Te_TargetGain[Te_Level] x Te_LifeIncrease))
                • Else - Actions
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • Te_ManaIncrease Greater than 0.00
                • Then - Actions
                  • Unit - Set mana of Te_Target[Te_LoopInt] to ((Mana of Te_Target[Te_LoopInt]) + (Te_TargetGain[Te_Level] x Te_ManaIncrease))
                • Else - Actions
            • Else - Actions
              • -------- ---------------------------------------------------------------------------------------------- --------
              • -------- ---------------------- If Deindex Condition is TRUE ----------------------- --------
              • -------- ---------------------------------------------------------------------------------------------- --------
              • -------- Destroy Handles --------
              • Lightning - Destroy Te_LinkEffect[Te_LoopInt]
              • Custom script: call DestroyGroup(udg_Te_AffectedUnits[udg_Te_LoopInt])
              • Special Effect - Destroy Te_SFXTarget[Te_LoopInt]
              • Special Effect - Destroy Te_SFXCaster[Te_LoopInt]
              • -------- Remove Bonus Speed --------
              • -------- Count how many times Te_Target is Tethered --------
              • Custom script: set i = 1
              • Custom script: set counter = 0
              • Custom script: set tempUnit = udg_Te_Target[udg_Te_LoopInt]
              • Custom script: loop
              • Custom script: exitwhen i > udg_Te_MaxIndex
              • Custom script: if tempUnit == udg_Te_Target[i] then
              • Custom script: set counter = counter + 1
              • Custom script: endif
              • Custom script: set i = i + 1
              • Custom script: endloop
              • Custom script: set tempUnit = null
              • Custom script: if counter == 1 then
              • Unit - Remove TeSpd_AbCode from Te_Target[Te_LoopInt]
              • Unit - Remove TeSpd_BuffCode buff from Te_Target[Te_LoopInt]
              • Custom script: endif
              • Unit - Remove TeSpd_AbCode from Te_Caster[Te_LoopInt]
              • Unit - Remove TeSpd_BuffCode buff from Te_Caster[Te_LoopInt]
              • Unit - Remove Te_AbConvert from Te_Caster[Te_LoopInt]
              • Unit - Remove TeBr_AbCode from Te_Caster[Te_LoopInt]
              • -------- Transfer Data --------
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • Te_LoopInt Not equal to Te_MaxIndex
                • Then - Actions
                  • Set Te_Caster[Te_LoopInt] = Te_Caster[Te_MaxIndex]
                  • Set Te_Target[Te_LoopInt] = Te_Target[Te_MaxIndex]
                  • Set Te_CasterHP[Te_LoopInt] = Te_CasterHP[Te_MaxIndex]
                  • Set Te_Latching[Te_LoopInt] = Te_Latching[Te_MaxIndex]
                  • Set Te_CasterMana[Te_LoopInt] = Te_CasterMana[Te_MaxIndex]
                  • Set Te_AffectedUnits[Te_LoopInt] = Te_AffectedUnits[Te_MaxIndex]
                  • Set Te_LinkEffect[Te_LoopInt] = Te_LinkEffect[Te_MaxIndex]
                  • Set Te_TimeLeft[Te_LoopInt] = Te_TimeLeft[Te_MaxIndex]
                  • Set Te_SFXTarget[Te_LoopInt] = Te_SFXTarget[Te_MaxIndex]
                  • Set Te_SFXCaster[Te_LoopInt] = Te_SFXCaster[Te_MaxIndex]
                  • Set Te_IndexedLevel[Te_LoopInt] = Te_IndexedLevel[Te_MaxIndex]
                  • Set Te_AboutToBreak[Te_LoopInt] = Te_AboutToBreak[Te_MaxIndex]
                  • Set Te_Owner[Te_LoopInt] = Te_Owner[Te_MaxIndex]
                • Else - Actions
              • -------- De-indexing --------
              • Set Te_MaxIndex = (Te_MaxIndex - 1)
              • Set Te_LoopInt = (Te_LoopInt - 1)
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • Te_MaxIndex Equal to 0
                • Then - Actions
                  • Trigger - Turn off Tether Periodic <gen>
                • Else - Actions

  • Tether Slow Periodic
    • Events
      • Time - Every 0.10 seconds of game time
    • Conditions
    • Actions
      • For each (Integer TeS_LoopInt) from 1 to TeS_MaxIndex, do (Actions)
        • Loop - Actions
          • -------- ----------------------------------------------------------------------------------------- --------
          • -------- ----------------------------------- Buff Timing --------------------------------- --------
          • -------- ----------------------------------------------------------------------------------------- --------
          • Set TeS_TimeLeft[TeS_LoopInt] = (TeS_TimeLeft[TeS_LoopInt] - 0.10)
          • -------- ----------------------------------------------------------------------------------------- --------
          • -------- ------------------------------ Duration Check -------------------------------- --------
          • -------- ----------------------------------------------------------------------------------------- --------
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • Or - Any (Conditions) are true
                • Conditions
                  • TeS_TimeLeft[TeS_LoopInt] Less than or equal to 0.00
                  • (TeS_Unit[TeS_LoopInt] is dead) Equal to True
            • Then - Actions
              • -------- Remove Slow --------
              • Unit - Remove TeS_AbCode from TeS_Unit[TeS_LoopInt]
              • Unit - Remove TeS_BuffCode buff from TeS_Unit[TeS_LoopInt]
              • -------- Transfer Data --------
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • TeS_LoopInt Not equal to TeS_MaxIndex
                • Then - Actions
                  • Set TeS_TimeLeft[TeS_LoopInt] = TeS_TimeLeft[TeS_MaxIndex]
                  • Set TeS_Unit[TeS_LoopInt] = TeS_Unit[TeS_MaxIndex]
                • Else - Actions
              • Set TeS_MaxIndex = (TeS_MaxIndex - 1)
              • Set TeS_LoopInt = (TeS_LoopInt - 1)
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • TeS_MaxIndex Equal to 0
                • Then - Actions
                  • Trigger - Turn off Tether Slow Periodic <gen>
                • Else - Actions
            • Else - Actions

IMPLEMENTATION
1) Make sure you check the "Automatically create unknown variables while pasting trigger data" in File->Preferences of World Editor.
2) Copy the 2 Custom Buffs
3) Copy the 5 Custom Abilities
4) Copy the whole "Spells" Trigger folder & paste in map.
5) Test the map.

Keywords:
tether, io, guardian wisp, link, line
Contents

Just another Warcraft III map (Map)

Reviews
Submission: Tether v1.03 Date: 1.09.2015 Status: Approved Rating: 4/5 Review Link Moderator: IcemanBo
Level 22
Joined
Feb 6, 2014
Messages
2,466
Changelog:
v1.02 [30 August 2015]
- Fixed a bug where the Tethered Unit will immediately lose its Speed Bonus when one Tether is broken and there is still an existing one.
- Tether Break will not continue to search for triggering unit index after that index was found, meaning the looping will stop.
- Tether Periodic is de-indexed directly.

v1.01 [22 August 2015]
- Tether Ability would be replaced by Break Tether Ability when currently using Tether, thus casting two Tether is no longer achievable.
- Destroyed an unused UnitGroup at Map Initialization.
- Latching Speed now configurable.
- Added some Attachment Effects on the Target and Caster
- Lightning Effect will change appearance when about to break caused by too much distance.
- Damage and Attack Type configurable.
- Lightning Movement now has Z-offset and changes height based on the target and caster's location.

v1.00 [10 August 2015]
- Initial Release
 
Last edited:
Level 22
Joined
Feb 6, 2014
Messages
2,466
Looks good Shadow :) may I ask why you check if TimeLeft is less than 0? It would just be better to equal it to zero because the duration would never go below it, no?
  • Set TeS_TimeLeft[TeS_LoopInt] Less than or equal to 0.00

For safety I guess, so that when I or the user change the periodic timer that will not result to exactly zero (i.e. 0.03 periodic time), then I wouldn't have to bother about calculating the exact value nearest to zero.

Another reason is if the user changed the slow duration to 2.01 with periodic timer of 0.1, the time left would never be exactly zero because it would be 0.01 then -0.09.
 
Last edited:
Level 22
Joined
Feb 6, 2014
Messages
2,466
-Break tether should be added when the ability is learned
-I'm not a fan of abilties taking up two command card slots
-Give the lightning some z offset
-The visuals could be a bit better

- Should I use Disable Ability for Players? That will make this MPI.
- Okay then, but I guess I have to use Custom scripts which users not knowing Jass may not understand.
- Like Attachment on the caster and tethered unit?
 
When activating tether you can replace the ability by "Deactivate Tether" ability.
It probably anyway would make more sense if your unit only can have one target at once, because you can't differ tethers when disabling them via ability.
And what about also adding the "Disable ability" also to the second affected unit? Might be used there, too, since they are allies anyway.

With unit groups creating there is same issue as mentioned in ground charge spell.

Directly deindex in loop when conditions are true, without doing/checking anything else then for deindex.
Also directly index when the distance is too large, so the tether would break.

Index owner of caster to reduce repetive function calls in loop.

Make damage- attacktype configurable.

If a unit is already indexed in slow system, you only might modify the level and duration if needed, but not necessarily to index it again if it's close the tether again.

The "latching speed" could be configurable.

I think there could be an effect for affected enemies, or changing vortex color temporary, just something visual.
 
Level 22
Joined
Feb 6, 2014
Messages
2,466
Ohh, double Tether was not meant to be created because the cooldown was expected to be set longer than the duration, but I will fix that such that when you cast Tether while another Tether is still on, it will break the earlier Tether.
EDIT: I just tested it and it doesn't fatal error to me
EDIT AGAIN: Double Tether can no longer be created.
 
Last edited:
Level 22
Joined
Feb 6, 2014
Messages
2,466
Done in my file, I just need to upload it and update description
EDIT: There is still some problems so I can't upload it at the moment.

When activating tether you can replace the ability by "Deactivate Tether" ability.
It probably anyway would make more sense if your unit only can have one target at once, because you can't differ tethers when disabling them via ability.
Done, Now players can't create Double Tether.
And what about also adding the "Disable ability" also to the second affected unit? Might be used there, too, since they are allies anyway.
Nah, there is no negative effect on the tethered unit so I don't see any reason why would he break Tether. It is like giving you the option to remove a positive buff.

With unit groups creating there is same issue as mentioned in ground charge spell.
Fixed. Destroyed Te_AffectedUnits at Map Init.

Directly deindex in loop when conditions are true, without doing/checking anything else then for deindex.
I don't get what you mean..

Also directly index when the distance is too large, so the tether would break.
Why? It will only decrease code readability making the trigger too long.

Index owner of caster to reduce repetive function calls in loop.
Done, the Level of Tether was also indexed.

Make damage- attacktype configurable.
Done.

If a unit is already indexed in slow system, you only might modify the level and duration if needed, but not necessarily to index it again if it's close the tether again.
Good call!

The "latching speed" could be configurable.
Done.

I think there could be an effect for affected enemies, or changing vortex color temporary, just something visual.
I attached effect and make some few changes on the lightning link effect..
 
EDIT: There is still some problems so I can't upload it at the moment.
Is this message still up to date?
______________________________________________

With deindexing I meant it should like this:
Loop
---- If any "Deindex condition" is true then
-------- Then
------------ Deindex
-------- Else
------------ All other actions

"Deindex condtion" might be if caster/target is dead or max distance is reached, etc.
So then nothing of the "other actions" part should run. It should just directly deindex.

Currently a unit can be targeted twice or even more by tether. If done so it will ignore all other tethers when first one gets canceled.
I mean it will be still indexed, yes, but the buff will disappear as it would be not in system anymore, which is wrong.
So it should not lose buff when still in system of an other tether, or it should be forbidden to tether a tethered unit.

In the end of loop in "Tether Break" you might throw in a
  • Custom script: exitwhen true
... to avoid further looping after the correct index has been found.

Visuals looks better:).
 
Level 5
Joined
Aug 20, 2015
Messages
133
Ohh, double Tether was not meant to be created because the cooldown was expected to be set longer than the duration, but I will fix that such that when you cast Tether while another Tether is still on, it will break the earlier Tether.
EDIT: I just tested it and it doesn't fatal error to me
EDIT AGAIN: Double Tether can no longer be created.

i mean, if ur caster1 will cast Thther on caster2, and caster2 will cast Tether on caster1, we will have double tether. thats what i mean. also those 2 casters will have great hp and mp regeneration boost
 
Level 5
Joined
Apr 13, 2008
Messages
184
Add an additional spell in

HEY! It would be awesome if u add an additional spell in. Its called back off!

The guardian wisp commands enemies to get away from it, doing damage around her and knocking them back to 25 units from it. If the guardian wisp has a soul mate, an explosion originates on them in addition, dealing the same damage and slowing by 25% for 2s. If an enemy would be hit by both blasts, they will only be affected by the one originating from the wisp.

Second is a spell that buffs only the wisp and the target hero.
 
Level 22
Joined
Feb 6, 2014
Messages
2,466
HEY! It would be awesome if u add an additional spell in. Its called back off!

The guardian wisp commands enemies to get away from it, doing damage around her and knocking them back to 25 units from it. If the guardian wisp has a soul mate, an explosion originates on them in addition, dealing the same damage and slowing by 25% for 2s. If an enemy would be hit by both blasts, they will only be affected by the one originating from the wisp.

Second is a spell that buffs only the wisp and the target hero.

Hmmm, I will just stick to normal Tether and kinda busy at the moment.

Spell updated to v1.02
 
Needed:
  • Also destroy group[1] onInit, not only group[0].
  • Don't do visuals part and location creations in periodic loop at very top.
    Only do so, if you don't deindex. If instance will deindex it is not needed.

Optional:
  • The "Or - Any Conditions" in periodic trigger is not needed, if you just switch the 'Else' and 'Then' parts.
  • Using the filter in "Pick every unit and do actions" operation is very long and unreadable.
    I recommend to make your own filter for these things inside the loop in GUI.

Bug was fixed, good.
 
Level 22
Joined
Feb 6, 2014
Messages
2,466
Needed:
  • Also destroy group[1] onInit, not only group[0].
  • Don't do visuals part and location creations in periodic loop at very top.
    Only do so, if you don't deindex. If instance will deindex it is not needed.

Optional:
  • The "Or - Any Conditions" in periodic trigger is not needed, if you just switch the 'Else' and 'Then' parts.
  • Using the filter in "Pick every unit and do actions" operation is very long and unreadable.
    I recommend to make your own filter for these things inside the loop in GUI.

Bug was fixed, good.
  • Oh right, I missed that one. Done
  • Got it. Done


  • If you mean use De Morgan's Theorem to prevent using OR, then it is done
  • Since, it is only optional, I will not do that part. It is because the GetEnumUnit() will be called a lot more times.
 
Oh, when unit added once to AffectedGroup it will never come out again.
So if it's standing like 30 seconds in teather lightning it will only receivce damage once, and the slow duration will also not refresh.
This is because all actions and checks will be ignored if picked unit already is in AffectedGroup.

Have not spotted any more mentionable things but this.

If you mean use De Morgan's Theorem to prevent using OR, then it is done
Yes, you have done it correctly.
 
Damage:
It seems a bit strange for me that time doesn't play a role at all.
For me, it would seem ok if it would take damage after a certain timeout again. - but naja ok.

Slow:
There is a part in code that you lookup for the index and then only update the TimeLeft. (instead of indexing to slow system)
But this part will never be able to run.
 
Level 22
Joined
Feb 6, 2014
Messages
2,466
Damage:
It seems a bit strange for me that time doesn't play a role at all.
For me, it would seem ok if it would take damage after a certain timeout again. - but naja ok.

Slow:
There is a part in code that you lookup for the index and then only update the TimeLeft. (instead of indexing to slow system)
But this part will never be able to run.

Well it was based on an ability in Dota and that was the mechanics of that spell ( I know, I'm not creative ).

Ahh yes, that is if you are hit by Tether while you have the Slow Buff. If that happens, the timer (or duration) will only refresh but the max index of the slow system is still the same. Thus, no unit can have more than one index in the Slow System.
 
Level 22
Joined
Feb 6, 2014
Messages
2,466
But the structure is like this:

If (UnitIsAffected == false) then
----
---- Unit - Damage
----
---- If UnitHasSlow == true
--------
-------- Unit - Slow_Refresh
---- Else
-------- Unit - Slow_Index
----
---- Unit - AddUnit to AffectedUnits

So once it was affected the update for slow won't be able to fire anymore.

Yes, but what if there are two Tethers. Tether from 1st Wisp hits Chieftain (in the test map) at time = 1.00. Then Tether from 2nd Wisp hits Chieftain at time = 1.50. Therefore, if the configured Slow Duration is for example 5 seconds, the Slow in Chieftain will be gone at time = 6.50.
 
Tether v1.03​

Date: August 1st, 2015

Concept: 3/5

Caster uses Tether to connect with an allied unit via a lightning.
Both units gain movementspeed, while the tether target also gains extra HP/MP -
regeneration when the caster regenerates.
When enemies come in touch with the tether lightning they will receive damage and get slowed.
At last the tether ends when the distance between connected units is too large, or the turn-off ability is used.

It is a good concept, but allowing multiple damage or multiple slowing would make much sense to me,
when brining a new, timing criteria into calculation.
Also the spell is as noted not unique, but an idea from dota.

Code: 4/5

Code is written well. It is MUI and leakless.
I personly like it that you used a second periodic loop for your slow system,
and did not put all together in one big bunch of code.
The only critique one could say is the O(n) search for deindex onBreak, but actually it's okay for me here.

Visuals: 3.5/5


Used effects are fitting the theme.
It is nice that the teather gets red before linked units get out of range.
What is missing is a special effect at an enemy unit when touching the tether, when receiving damage/gets slowed.

Conclusion:

Approved

Rating: 4/5

 
Level 22
Joined
Feb 6, 2014
Messages
2,466
I was testing this in the editor and crashed with an fatal error.
Last thing i did was bind the two wisps with each other and try damage the shamans blob with the chieftain aggroing in too.
Id like to believe it has involved something with 'Purge' of Shamans as one was playing their spell animation.

Thanks for telling me that, I'll try to recreate that. Maybe it involves something with removing buffs.

EDIT:
Doesn't happen to me at all, I tried making my own Shaman and purging the Wisps tethered together but it just doesn't crash. Maybe the problem is in your PC, perhaps it cannot handle the stacking regeneration.
 
Last edited:
Top