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

Soul Tether V1.01

As opposed to my regular, long spells I thought I'd make something pretty quickly (Admittedly "quickly" was a while on this one since most of the time was spent messing around on other sites)

I felt like doing a utility spell (one which doesn't actually deal /any/ damage /ever/) which would apply in multiple situations to either tip a battle in your favour or to win a crushing battle with nearly no losses
Eitherway heres Soul Tether:


Summons a Soul Tether at the target point. The Soul Tether will take hold of enemy units' souls when they become weak, restoring their power and giving control to the caster, however as a penalty they must remain close to the Tether to sustain themselves, and will die without it. The Tether can sustain their lives for a short time.

Level 1 - 250 AOE, 15 second duration, sustains for 7.5 seconds
Level 2 - 300 AOE, 20 second duration, sustains for 10 seconds
Level 3 - 350 AOE, 25 second duration, sustains for 12.5 seconds



- Heavily Configurable
- Dynamically indexed
- Eye Candy
- Utility spell
- Much shorter than my normal spells



  • Soul Tether Configuration
    • Events
      • Map initialization
    • Conditions
    • Actions
      • -------- -------- --------
      • -------- Determines the percentage of health needed to take control of a soul --------
      • Set ST_TriggeringHealthPercent = 20.00
      • -------- Determines the area that the Tether will revive/hold units --------
      • Set ST_AoeBase = 200.00
      • Set ST_AoePerLevel = 50.00
      • -------- Determines how much "space" in the barrier each rune reprisents --------
      • -------- Decrease - More Barrier Segments, Increase - Fewer Barrier Segments --------
      • Set ST_BarrierSpaceTaken = 10.00
      • -------- Determines how transparent a revived unit is --------
      • Set ST_UnitTransparency = 75.00
      • -------- Determines how much damage a unit takes when the tether is gone/they leave the range of the tether --------
      • Set ST_HealthPenaltyPerSecond = 250.00
      • -------- Determines how long the Tether will last for (seconds) --------
      • Set ST_TetherDurationBase = 10.00
      • Set ST_TetherDurationPerLevel = 5.00
      • -------- Determines how long the Tether can hold onto the souls of the fallen --------
      • Set ST_UndeadDurationBase = 5.00
      • Set ST_UndeadDurationPerLevel = 2.50
      • -------- Determines Lightning Colouration --------
      • Set ST_LightningRed = 1.00
      • Set ST_LightningGreen = 1.00
      • Set ST_LightningBlue = 0.00
      • -------- Determines the scaling of the spawn sfx --------
      • Set ST_EffectScalingSpawn = 150.00
      • -------- Determines the Height given to the lightning effects --------
      • Set ST_LightningZ = 100.00
      • -------- Determines the unit model used as the Tether --------
      • Set ST_TetherModel = buildings\other\BookOfSummoning\BookOfSummoning.mdl
      • -------- Determines the unit model used to reprisent the edge of the Tether's range --------
      • Set ST_BarrierModel = Doodads\Cinematic\GlowingRunes\GlowingRunes2.mdl
      • -------- Determines the SFX used to create create the spell --------
      • Set ST_SpawnSFX = Abilities\Spells\Undead\DarkRitual\DarkRitualTarget.mdl
      • -------- Determines the SFX used to End the spell --------
      • Set ST_DissappearenceSFX = Abilities\Spells\Undead\DarkRitual\DarkRitualTarget.mdl
      • -------- Determines the Lightning Effect used --------
      • Set ST_LightningEffect = CLPB
      • -------- Determines the spell used to act as the activation spell --------
      • Set ST_Spell = Soul Tether
      • -------- Determines the Dummy used to attach all the effects to --------
      • Set ST_DummyType = Soul Tether
  • Soul Tether Activation
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to ST_Spell
    • Actions
      • Set ST_TempPoint = (Target point of ability being cast)
      • Unit - Create 1 ST_DummyType for Neutral Passive at ST_TempPoint facing Default building facing degrees
      • Set ST_TempUnit = (Last created unit)
      • Special Effect - Create a special effect attached to the origin of ST_TempUnit using ST_SpawnSFX
      • Special Effect - Destroy (Last created special effect)
      • Animation - Change ST_TempUnit's size to (ST_EffectScalingSpawn%, 0.00%, 0.00%) of its original size
      • Unit - Add a 1.00 second Generic expiration timer to ST_TempUnit
      • Unit - Create 1 ST_DummyType for Neutral Passive at ST_TempPoint facing Default building facing degrees
      • Set ST_TempUnit = (Last created unit)
      • Set ST_TempUnit3 = (Triggering unit)
      • Special Effect - Create a special effect attached to the origin of ST_TempUnit using ST_TetherModel
      • Set ST_MaxIndex = (ST_MaxIndex + 1)
      • Set ST_OriginalCaster[ST_MaxIndex] = ST_TempUnit3
      • Set ST_TempReal = (Real((Level of ST_Spell for ST_TempUnit3)))
      • Set ST_SpecialEffect[ST_MaxIndex] = (Last created special effect)
      • Unit - Add a (ST_TetherDurationBase + (ST_TetherDurationPerLevel x ST_TempReal)) second Generic expiration timer to ST_TempUnit
      • Set ST_UndeadDuration[ST_MaxIndex] = (ST_UndeadDurationBase + (ST_UndeadDurationPerLevel x ST_TempReal))
      • Set ST_Core[ST_MaxIndex] = ST_TempUnit
      • Set ST_Aoe[ST_MaxIndex] = (ST_AoeBase + (ST_AoePerLevel x ST_TempReal))
      • Set ST_UnitIndex[ST_MaxIndex] = ST_TempUnit
      • Set ST_StageID[ST_MaxIndex] = 1
      • Set ST_TempInteger = (Integer((ST_Aoe[ST_MaxIndex] / ST_BarrierSpaceTaken)))
      • Set ST_TempReal = ST_Aoe[ST_MaxIndex]
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • ST_MaxIndex Equal to 1
        • Then - Actions
          • Trigger - Turn on Soul Tether Loop <gen>
        • Else - Actions
      • For each (Integer ST_Index) from 1 to ST_TempInteger, do (Actions)
        • Loop - Actions
          • Set ST_Angle = (ST_Angle + (360.00 / (Real(ST_TempInteger))))
          • Set ST_TempPoint2 = (ST_TempPoint offset by ST_TempReal towards ST_Angle degrees)
          • Unit - Create 1 ST_DummyType for Neutral Passive at ST_TempPoint2 facing Default building facing degrees
          • Set ST_TempUnit2 = (Last created unit)
          • Special Effect - Create a special effect attached to the origin of ST_TempUnit2 using ST_BarrierModel
          • Set ST_MaxIndex = (ST_MaxIndex + 1)
          • Set ST_StageID[ST_MaxIndex] = 3
          • Set ST_SpecialEffect[ST_MaxIndex] = (Last created special effect)
          • Set ST_OriginalCaster[ST_MaxIndex] = ST_TempUnit3
          • Set ST_UnitIndex[ST_MaxIndex] = ST_TempUnit2
          • Set ST_Core[ST_MaxIndex] = ST_TempUnit
          • Custom script: call RemoveLocation (udg_ST_TempPoint2)
      • Custom script: call RemoveLocation (udg_ST_TempPoint)
  • Soul Tether Loop
    • Events
      • Time - Every 0.03 seconds of game time
    • Conditions
    • Actions
      • For each (Integer ST_Index) from 1 to ST_MaxIndex, do (Actions)
        • Loop - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • ST_StageID[ST_Index] Equal to 1
            • Then - Actions
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • (ST_UnitIndex[ST_Index] is alive) Equal to True
                • Then - Actions
                  • Set ST_TempPoint = (Position of ST_UnitIndex[ST_Index])
                  • Set ST_TempGroup = (Units within ST_Aoe[ST_Index] of ST_TempPoint)
                  • Unit Group - Pick every unit in ST_TempGroup and do (Actions)
                    • Loop - Actions
                      • Set ST_TempUnit = (Picked unit)
                      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                        • If - Conditions
                          • (ST_TempUnit is A structure) Equal to False
                          • (ST_TempUnit is alive) Equal to True
                          • ((Unit-type of ST_TempUnit) is Magic Immune) Equal to False
                          • (ST_TempUnit belongs to an enemy of (Owner of ST_OriginalCaster[ST_Index])) Equal to True
                          • (Percentage life of ST_TempUnit) Less than or equal to ST_TriggeringHealthPercent
                          • (ST_TempUnit is A Hero) Equal to False
                          • (ST_TempUnit is A ground unit) Equal to True
                          • (ST_TempUnit is Mechanical) Equal to False
                        • Then - Actions
                          • Unit - Change ownership of ST_TempUnit to (Owner of ST_OriginalCaster[ST_Index]) and Change color
                          • Unit - Set life of ST_TempUnit to 100.00%
                          • Animation - Change ST_TempUnit's vertex coloring to (100.00%, 100.00%, 100.00%) with ST_UnitTransparency% transparency
                          • Unit - Add a ST_UndeadDuration[ST_Index] second Generic expiration timer to ST_TempUnit
                          • Unit - Make ST_TempUnit Explode on death
                          • Set ST_TempPoint2 = (Position of ST_TempUnit)
                          • Set ST_MaxIndex = (ST_MaxIndex + 1)
                          • Set ST_Core[ST_MaxIndex] = ST_UnitIndex[ST_Index]
                          • Set ST_OriginalCaster[ST_MaxIndex] = ST_OriginalCaster[ST_Index]
                          • Set ST_Aoe[ST_MaxIndex] = ST_Aoe[ST_Index]
                          • Set ST_UnitIndex[ST_MaxIndex] = ST_TempUnit
                          • Set ST_StageID[ST_MaxIndex] = 2
                          • Custom script: set udg_ST_TempX = GetUnitX(udg_ST_TempUnit)
                          • Custom script: set udg_ST_TempY = GetUnitY(udg_ST_TempUnit)
                          • Custom script: set udg_ST_TempX2 = GetUnitX(udg_ST_Core[udg_ST_Index])
                          • Custom script: set udg_ST_TempY2 = GetUnitY(udg_ST_Core[udg_ST_Index])
                          • Custom script: set udg_ST_TempZ = GetLocationZ(udg_ST_TempPoint2) + udg_ST_LightningZ
                          • Custom script: set udg_ST_TempZ2 = GetLocationZ(udg_ST_TempPoint) + udg_ST_LightningZ
                          • Custom script: set udg_ST_CurrentLightningEffect[udg_ST_MaxIndex] = AddLightningEx(udg_ST_LightningEffect, true, udg_ST_TempX2, udg_ST_TempY2, udg_ST_TempZ2, udg_ST_TempX, udg_ST_TempY, udg_ST_TempZ)
                          • Lightning - Change color of ST_CurrentLightningEffect[ST_MaxIndex] to (ST_LightningRed ST_LightningGreen ST_LightningBlue) with 1.00 alpha
                          • Custom script: call RemoveLocation (udg_ST_TempPoint2)
                        • Else - Actions
                  • Custom script: call RemoveLocation (udg_ST_TempPoint)
                  • Custom script: call DestroyGroup(udg_ST_TempGroup)
                • Else - Actions
                  • Set ST_UnitIDStorage = ST_UnitIndex[ST_Index]
                  • Special Effect - Create a special effect attached to the origin of ST_UnitIndex[ST_Index] using ST_DissappearenceSFX
                  • Special Effect - Destroy (Last created special effect)
                  • For each (Integer ST_SecondaryIndex) from 1 to ST_MaxIndex, do (Actions)
                    • Loop - Actions
                      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                        • If - Conditions
                          • ST_Core[ST_SecondaryIndex] Equal to ST_UnitIDStorage
                        • Then - Actions
                          • Unit - Add a 0.60 second Generic expiration timer to ST_UnitIndex[ST_SecondaryIndex]
                          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                            • If - Conditions
                              • ST_StageID[ST_SecondaryIndex] Equal to 2
                            • Then - Actions
                              • Lightning - Destroy ST_CurrentLightningEffect[ST_SecondaryIndex]
                            • Else - Actions
                              • Special Effect - Destroy ST_SpecialEffect[ST_SecondaryIndex]
                          • Set ST_OriginalCaster[ST_SecondaryIndex] = ST_OriginalCaster[ST_MaxIndex]
                          • Set ST_CurrentLightningEffect[ST_SecondaryIndex] = ST_CurrentLightningEffect[ST_MaxIndex]
                          • Set ST_SpecialEffect[ST_SecondaryIndex] = ST_SpecialEffect[ST_MaxIndex]
                          • Set ST_UndeadDuration[ST_SecondaryIndex] = ST_UndeadDuration[ST_MaxIndex]
                          • Set ST_Core[ST_SecondaryIndex] = ST_Core[ST_MaxIndex]
                          • Set ST_Aoe[ST_SecondaryIndex] = ST_Aoe[ST_MaxIndex]
                          • Set ST_UnitIndex[ST_SecondaryIndex] = ST_UnitIndex[ST_MaxIndex]
                          • Set ST_StageID[ST_SecondaryIndex] = ST_StageID[ST_MaxIndex]
                          • Set ST_MaxIndex = (ST_MaxIndex - 1)
                          • Set ST_SecondaryIndex = (ST_SecondaryIndex - 1)
                          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                            • If - Conditions
                              • ST_MaxIndex Equal to 0
                            • Then - Actions
                              • Trigger - Turn off (This trigger)
                            • Else - Actions
                        • Else - Actions
            • Else - Actions
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • ST_StageID[ST_Index] Equal to 2
                • Then - Actions
                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    • If - Conditions
                      • (ST_UnitIndex[ST_Index] is alive) Equal to True
                    • Then - Actions
                      • Set ST_TempPoint = (Position of ST_UnitIndex[ST_Index])
                      • Set ST_TempPoint2 = (Position of ST_Core[ST_Index])
                      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                        • If - Conditions
                          • (Distance between ST_TempPoint and ST_TempPoint2) Greater than ST_Aoe[ST_Index]
                        • Then - Actions
                          • Unit - Cause ST_OriginalCaster[ST_Index] to damage ST_UnitIndex[ST_Index], dealing (ST_HealthPenaltyPerSecond x 0.03) damage of attack type Spells and damage type Normal
                        • Else - Actions
                      • Custom script: set udg_ST_TempX = GetUnitX(udg_ST_UnitIndex[udg_ST_Index])
                      • Custom script: set udg_ST_TempY = GetUnitY(udg_ST_UnitIndex[udg_ST_Index])
                      • Custom script: set udg_ST_TempX2 = GetUnitX(udg_ST_Core[udg_ST_Index])
                      • Custom script: set udg_ST_TempY2 = GetUnitY(udg_ST_Core[udg_ST_Index])
                      • Custom script: call MoveLightningEx(udg_ST_CurrentLightningEffect[udg_ST_Index], true, udg_ST_TempX2, udg_ST_TempY2, udg_ST_TempZ2, udg_ST_TempX, udg_ST_TempY, udg_ST_TempZ)
                      • Custom script: call RemoveLocation (udg_ST_TempPoint2)
                      • Custom script: call RemoveLocation (udg_ST_TempPoint)
                    • Else - Actions
                      • Lightning - Destroy ST_CurrentLightningEffect[ST_Index]
                      • Set ST_OriginalCaster[ST_Index] = ST_OriginalCaster[ST_MaxIndex]
                      • Set ST_SpecialEffect[ST_Index] = ST_SpecialEffect[ST_MaxIndex]
                      • Set ST_UndeadDuration[ST_Index] = ST_UndeadDuration[ST_MaxIndex]
                      • Set ST_Core[ST_Index] = ST_Core[ST_MaxIndex]
                      • Set ST_Aoe[ST_Index] = ST_Aoe[ST_MaxIndex]
                      • Set ST_UnitIndex[ST_Index] = ST_UnitIndex[ST_MaxIndex]
                      • Set ST_StageID[ST_Index] = ST_StageID[ST_MaxIndex]
                      • Set ST_CurrentLightningEffect[ST_Index] = ST_CurrentLightningEffect[ST_MaxIndex]
                      • Set ST_MaxIndex = (ST_MaxIndex - 1)
                      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                        • If - Conditions
                          • ST_MaxIndex Equal to 0
                        • Then - Actions
                          • Trigger - Turn off (This trigger)
                        • Else - Actions
                • Else - Actions



-=V1.00=-
- Initial upload
- Expect errors
-=V1.01=-
- Corrected a comment in the configuration
- Used another TempUnit variable to avoid a double (triggering unit) call


If you find any bugs/glitches/problems/etc. Post a message so I can get to work on it immediately

Give credits if you use this spell and do not re-distribute without my permission.

Keywords:
Soul, Possess, Take Control, Tether, Chain, Slave, Fade, Spirit, AOE, Timed Life, Summon.
Contents

Soul Tether (Map)

Reviews
21:25, 18th Jul 2012 Magtheridon96: Approved. 4/5. This spell is well done. Since you're using TempPoint2 for calculating Location Z, I'd suggest making it a static location (meaning you never destroy it) On initialization, set it to...

Moderator

M

Moderator

21:25, 18th Jul 2012
Magtheridon96: Approved.
4/5.

This spell is well done.

Since you're using TempPoint2 for calculating Location Z, I'd suggest making it a static location (meaning you never destroy it)
On initialization, set it to Location(0, 0) using custom scripts (set udg_TempLoc2 = Location(0, 0))
Then, when you want to calculate Z, all you would do is call MoveLocation.
That native function takes a location and 2 reals (x and y).
call MoveLocation(udg_TempLoc2, x, y)

In fact, you can rename it to ZLoc or zLoc because most people use
that name for their static Z-finding locations.

Also, instead of repeating the triggering unit call in the cast trigger,
you can initially store it in a normal unit variable, set the current
instance's caster to it, and use the variable inside the loop.

I hope this approval won't be another mistake.


edit
Okay, fair enough.
 
Level 1
Joined
Feb 9, 2016
Messages
1
Looks good,works well,performs amazing and code is noob(read:me) friendly.+5 and rep.
 
Top