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:
Tooltip
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
Features
- Heavily Configurable
- Dynamically indexed
- Eye Candy
- Utility spell
- Much shorter than my normal spells
Triggers
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)
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)
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)
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
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
Changelog
-=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.
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). callMoveLocation(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.