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

LITHUFFIN's dark spells 3.00

This bundle is marked as useful / simple. Simplicity is bliss, low effort and/or may contain minor bugs.
  • Like
Reactions: deepstrasz
Well it isn't my spell, LITHUFFIN made it originally so the idea and concept goes to him however who fixed it and actually made it a spell that can be approved/reviewed is me. So credit me for coding/triggering the spells and credit LITHUFFIN for the idea of it.

Dark helper works by targeting a point to pop down a target marker where a deathcoil comes walking by shooting balls at nearby targets, lasts for 5 seconds.

Shadow move works by targeting a unit then your unit begins to charge towards the targeted unit and when in close enough range you begin to push the target away in-front of you as you continue charging for the rest of the duration however this won't happen if you can't get to the target before the duration is over.

[trigger=Dark Helper]
Dark Helper Config
Events
Time - Elapsed game time is 0.00 seconds
Conditions
Actions
Set DH_ability = Dark Helper
Set DH_DamageAbility = Dummy Ability
Set DHsfx[1] = Abilities\Spells\Undead\DeathCoil\DeathCoilMissile.mdl
Set DHsfx[2] = Abilities\Spells\NightElf\TrueshotAura\TrueshotAura.mdl
[/trigger][trigger=]
Dark Helper
Events
Unit - A unit Starts the effect of an ability
Conditions
(Ability being cast) Equal to DH_ability
Actions
Set DH_index = (DH_index + 1)
Set DH_time[DH_index] = 5
-------- You can configure damage and model in object editor. --------
Set TempPoint = (Target point of ability being cast)
Set TempUnit = (Triggering unit)
Set TempPlayer = (Triggering player)
Set TempPoint2 = (Position of TempUnit)
Unit - Create 1 Test Dummy Unit for TempPlayer at TempPoint2 facing TempPoint
Set DH_unit[DH_index] = (Last created unit)
Special Effect - Create a special effect attached to the origin of DH_unit[DH_index] using DHsfx[1]
Set DH_sfx[DH_index] = (Last created special effect)
-------- This is how long the dummy unit will last for. --------
Unit - Order DH_unit[DH_index] to Move To TempPoint
Custom script: set udg_TempPlayer = null
-------- The sfx/model here represents the aura/target point where the dummy unit moves too. --------
Unit - Create 1 Test Dummy Unit for Neutral Passive at TempPoint facing TempPoint
Set DHeffect[DH_index] = (Last created unit)
Unit - Remove DH_DamageAbility from DHeffect[DH_index]
Special Effect - Create a special effect attached to the origin of DHeffect[DH_index] using DHsfx[2]
Set DH_sfx2[DH_index] = (Last created special effect)
Custom script: call RemoveLocation (udg_TempPoint)
Custom script: call RemoveLocation (udg_TempPoint2)
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
If - Conditions
DH_index Equal to 1
Then - Actions
Custom script: call TimerStart(udg_DH_timer, 0.031200, true, null)
Else - Actions
[/trigger][trigger=]

DHloop
Events
Time - DH_timer expires
Conditions
Actions
For each (Integer DH_loop) from 1 to DH_index, do (Actions)
Loop - Actions
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
If - Conditions
DH_time[DH_loop] Less than or equal to 0
Then - Actions
Unit - Kill DH_unit[DH_loop]
Unit - Kill DHeffect[DH_loop]
Special Effect - Destroy DH_sfx[DH_loop]
Special Effect - Destroy DH_sfx2[DH_loop]
Set DH_sfx[DH_loop] = DH_sfx[DH_index]
Set DH_sfx2[DH_loop] = DH_sfx2[DH_index]
Set DH_unit[DH_loop] = DH_unit[DH_index]
Set DH_unit[DH_index] = No unit
Set DHeffect[DH_loop] = DHeffect[DH_index]
Set DHeffect[DH_index] = No unit
Set DH_time[DH_loop] = DH_time[DH_index]
Set DH_index = (DH_index - 1)
Set DH_loop = (DH_loop - 1)
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
If - Conditions
DH_index Equal to 0
Then - Actions
Countdown Timer - Pause DH_timer
Else - Actions

Else - Actions
Set DH_time[DH_loop] = (DH_time[DH_loop] - 1)

[/trigger]


[trigger=start config]
Shadow Move Config
Events
Time - Elapsed game time is 0.00 seconds
Conditions
Actions
Set TS_ShadowAttackType = Spells
Set TS_ShadowDMGType = Universal
-------- The spell itself. --------
Set Cnfg_Shadow_Move_Ability = Shadow Move
-------- The special effect for moving --------
Set TS_ShadowFX = Objects\Spawnmodels\Human\FragmentationShards\FragBoomSpawn.mdl
Set TS_ShadowFX_2 = Objects\Spawnmodels\Human\FragmentationShards\FragBoomSpawn.mdl

[/trigger]
[trigger=]
Shadow Move
Events
Unit - A unit Starts the effect of an ability
Conditions
(Ability being cast) Equal to Cnfg_Shadow_Move_Ability
Actions
Set TS_shadowindex = (TS_shadowindex + 1)
Set TS_Shadow_Move_Caster[TS_shadowindex] = (Triggering unit)
Unit - Turn collision for TS_Shadow_Move_Caster[TS_shadowindex] Off
Set TS_Shadow_Move_Target[TS_shadowindex] = (Target unit of ability being cast)
Set TS_Shadow_Move_TPL[TS_shadowindex] = (Owner of TS_Shadow_Move_Target[TS_shadowindex])
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
If - Conditions
(Level of Invulnerable (Neutral) for TS_Shadow_Move_Target[TS_shadowindex]) Greater than 0
Then - Actions
Set DatOriginallyInvulCheck[TS_shadowindex] = True
Else - Actions
-------- The duration of the spell. --------
Set TS_Shadow_Move_Dur[TS_shadowindex] = 3.00
-------- The damage dealt every 0.03 seconds --------
Set Cnfg_Shadow_Move_Damage[TS_shadowindex] = 1.50
-------- The distance obtained every 0.03 seconds --------
Set Cnfg_Shadow_Move_Distance[TS_shadowindex] = 15.00
Unit - Make TS_Shadow_Move_Target[TS_shadowindex] face TS_Shadow_Move_Caster[TS_shadowindex] over 0.00 seconds
Unit - Order TS_Shadow_Move_Target[TS_shadowindex] to Hold Position
Unit - Change ownership of TS_Shadow_Move_Target[TS_shadowindex] to Neutral Passive and Retain color
Unit - Add Invulnerable (Neutral) to TS_Shadow_Move_Target[TS_shadowindex]
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
If - Conditions
TS_shadowindex Equal to 1
Then - Actions
Custom script: call TimerStart(udg_SM_timer, 0.031200, true, null)
Else - Actions

[/trigger]
[trigger=Shadow Move]
Shadow Move Loop
Events
Time - SM_timer expires
Conditions
Actions
For each (Integer TS_shadowloop) from 1 to TS_shadowindex, do (Actions)
Loop - Actions
Set TS_Shadow_Move_Dur[TS_shadowloop] = (TS_Shadow_Move_Dur[TS_shadowloop] - 0.03)
Set TS_Shadow_Move_TP = (Position of TS_Shadow_Move_Caster[TS_shadowloop])
Set TS_Shadow_Move_TP3 = (Position of TS_Shadow_Move_Target[TS_shadowloop])
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
If - Conditions
TS_Shadow_Move_Dur[TS_shadowloop] Greater than 0.00
(TS_Shadow_Move_Caster[TS_shadowloop] is dead) Not equal to True
(TS_Shadow_Move_Target[TS_shadowloop] is dead) Not equal to True
(Terrain pathing at TS_Shadow_Move_TP of type Walkability is off) Equal to False
(Terrain pathing at TS_Shadow_Move_TP3 of type Walkability is off) Equal to False
Then - Actions
Set TS_Shadow_Move_TP2 = (TS_Shadow_Move_TP offset by Cnfg_Shadow_Move_Distance[TS_shadowloop] towards (Facing of TS_Shadow_Move_Caster[TS_shadowloop]) degrees)
Unit - Move TS_Shadow_Move_Caster[TS_shadowloop] instantly to TS_Shadow_Move_TP2
Unit - Make TS_Shadow_Move_Caster[TS_shadowloop] face TS_Shadow_Move_TP3 over 0.00 seconds
Unit - Make TS_Shadow_Move_Target[TS_shadowloop] face TS_Shadow_Move_TP over 0.00 seconds
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
If - Conditions
(Random integer number between 1 and 2) Equal to 1
Then - Actions
Special Effect - Create a special effect at TS_Shadow_Move_TP using TS_ShadowFX
Special Effect - Destroy (Last created special effect)
Else - Actions
Custom script: call RemoveLocation(udg_TS_Shadow_Move_TP2)
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
If - Conditions
(Distance between TS_Shadow_Move_TP and TS_Shadow_Move_TP3) Greater than 100.00
Then - Actions
Else - Actions
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
If - Conditions
(Level of Invulnerable (Neutral) for TS_Shadow_Move_Target[TS_shadowloop]) Greater than 0
Then - Actions
Unit - Remove Invulnerable (Neutral) from TS_Shadow_Move_Target[TS_shadowloop]
Unit - Turn collision for TS_Shadow_Move_Target[TS_shadowloop] Off
Unit - Change ownership of TS_Shadow_Move_Target[TS_shadowloop] to TS_Shadow_Move_TPL[TS_shadowloop] and Retain color
Unit - Make TS_Shadow_Move_Target[TS_shadowloop] face TS_Shadow_Move_Caster[TS_shadowloop] over 0.00 seconds
Else - Actions
Set TS_Shadow_Move_TP2 = (TS_Shadow_Move_TP3 offset by Cnfg_Shadow_Move_Distance[TS_shadowloop] towards (Facing of TS_Shadow_Move_Caster[TS_shadowloop]) degrees)
Unit - Move TS_Shadow_Move_Target[TS_shadowloop] instantly to TS_Shadow_Move_TP2
Unit - Cause TS_Shadow_Move_Caster[TS_shadowloop] to damage TS_Shadow_Move_Target[TS_shadowloop], dealing Cnfg_Shadow_Move_Damage[TS_shadowloop] damage of attack type TS_ShadowAttackType and damage type TS_ShadowDMGType
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
If - Conditions
(Random integer number between 1 and 2) Equal to 1
Then - Actions
Special Effect - Create a special effect attached to the overhead of TS_Shadow_Move_Target[TS_shadowloop] using TS_ShadowFX_2
Special Effect - Destroy (Last created special effect)
Else - Actions
Custom script: call RemoveLocation(udg_TS_Shadow_Move_TP2)
Else - Actions
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
If - Conditions
DatOriginallyInvulCheck[TS_shadowloop] Equal to True
Then - Actions
Unit - Add Invulnerable (Neutral) to TS_Shadow_Move_Target[TS_shadowloop]
Else - Actions
Unit - Change ownership of TS_Shadow_Move_Target[TS_shadowloop] to TS_Shadow_Move_TPL[TS_shadowloop] and Retain color
Set TS_Shadow_Move_Dur[TS_shadowloop] = TS_Shadow_Move_Dur[TS_shadowindex]
Set Cnfg_Shadow_Move_Distance[TS_shadowloop] = Cnfg_Shadow_Move_Distance[TS_shadowindex]
Set Cnfg_Shadow_Move_Damage[TS_shadowloop] = Cnfg_Shadow_Move_Damage[TS_shadowindex]
Unit - Turn collision for TS_Shadow_Move_Caster[TS_shadowloop] On
Unit - Turn collision for TS_Shadow_Move_Target[TS_shadowloop] On
Set TS_Shadow_Move_TPL[TS_shadowloop] = TS_Shadow_Move_TPL[TS_shadowindex]
Custom script: set udg_TS_Shadow_Move_TPL[udg_TS_shadowindex] = null
Set TS_Shadow_Move_Target[TS_shadowloop] = TS_Shadow_Move_Target[TS_shadowindex]
Set TS_Shadow_Move_Target[TS_shadowindex] = No unit
Set TS_Shadow_Move_Caster[TS_shadowloop] = TS_Shadow_Move_Caster[TS_shadowindex]
Set TS_Shadow_Move_Caster[TS_shadowindex] = No unit
Set DatOriginallyInvulCheck[TS_shadowloop] = False
Set DatOriginallyInvulCheck[TS_shadowloop] = DatOriginallyInvulCheck[TS_shadowindex]
Set TS_shadowindex = (TS_shadowindex - 1)
Set TS_shadowloop = (TS_shadowloop - 1)
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
If - Conditions
TS_shadowindex Equal to 0
Then - Actions
Countdown Timer - Pause SM_timer
Else - Actions
Custom script: call RemoveLocation(udg_TS_Shadow_Move_TP)
Custom script: call RemoveLocation(udg_TS_Shadow_Move_TP3)

[/trigger]

I figured LITHUFFIN wouldn't mind this since he already tried submitting it here and well if there is a problem I will take this off/down. =)

Keywords:
dat,-,c,3,d,t,a,l,phoenix,epic,trigger,gui,dark,pack,spells,spellpack,L,I,T,H,U,F,F,I,N
Contents

Custom dark spells update #3 (Map)

Reviews
12th Dec 2015 IcemanBo: For long time as NeedsFix. Rejected. 00:38, 17th Feb 2015 IcemanBo: http://www.hiveworkshop.com/forums/spells-569/lithuffins-dark-spells-3-00-a-256348/index2.html#post2654133 13:31, 5th Jan 2015 IcemanBo...
Taking first post, original thread is http://www.hiveworkshop.com/forums/spells-569/shadow-move-1-00-a-256330/

Will update this spell later when I have the time, still missing some configurable options and some other stuff such as improved timer event and movement functions.

Edit: Fixed variable naming and added more configurable options, just missing timer event and movement.
 
Last edited:
Level 19
Joined
Jul 14, 2011
Messages
875
What he meant is create a trigger that runs every X seconds (prefferably 0.03125), and for every instance of the spell have a real getting increased by that X, and gets checked if the duration is reached.
Something about my sentence sounds really wrong but I'm not sure what :vw_wtf:
 
Level 19
Joined
Jul 14, 2011
Messages
875
Yup agreed, I don't think it has an exact accurate number like 0.27 though.

I remember reading something and that number has been in my head for weeks. It's ~0.20 for sure.
Either way, the wait gets even more inaccurate depending on the players ping, on the other hand PolledWait can bug out, although extremely rarely, and contunues countnig even when a player is lagging out I think.
 

Wrda

Spell Reviewer
Level 25
Joined
Nov 18, 2012
Messages
1,870
No one will cry because of an additional +0.05~0.27s. The wait here doesn't do any harm.
Both PooledWait and normal Wait continue counting when a player is lagging or when the game is paused. I don't think the wait gets more inaccurate depending on the players ping, but yes on the game delay.
 
Last edited:
Some notes:

Dark Helper:

Create a config trigger, which should include:
-Variable for DummyUnit

-
Variable for the spell's duration

-
Variable for the Special Effect


  • Set TempUnit = (Triggering unit)
  • Set TempPlayer = (Owner of TempUnit)
  • Set TempPoint2 = (Position of TempUnit)
-->
  • Set TempPlayer = (Triggering Player)
  • Set TempPoint2 = (Position of (Triggering unit))
  • Unit - Add a 5.00 second Generic expiration timer to (Last created unit)
  • Unit - Order (Last created unit) to Move To TempPoint
^Use the temp unit variable to gain performance.

Why do you nulling "TempUnit"? In next cast it gets a new value again.
There is never a need to null players, doesn't matter they are global or local. They are constant and never get destroyed/removed.
Null the local effect in and of trigger.

Change the variable and object data names for an easy identification towards the spell: prefix_Name

Shadow Move:


  • Set TS_Shadow_Move_TPL[TS_shadowindex] = (Owner of TS_Shadow_Move_TUOABC[TS_shadowindex])
-->
Set TS_Shadow_Move_TPL[TS_shadowindex] = (Triggering Player))

The ITE where you check to turn off the loop trigger should be moved into the deindex part.

"Invulnerable (Neutral)" should be binded to the spell custom spells, as it can cause bugs since the user also might add this ability to any unit without using this system.

  • (Random integer number between 1 and 2) Equal to 1
^You can replace this by a boolean[index] which you always change between true/false to gain performance.
If true you create a special effect and set it "false". Else you just set it "true".

AttackType and DamageType should be configurable.

Other units may block the caster, so it will never reach the targeted unit. Fix this, please.

So variable names should be improved. A name should say something about the intention of the variable.
For example, I would never know what following variables should represent, if I would not see the input:
  • Set TS_Shadow_Move_CU
  • Set TS_Shadow_Move_TUOABC
  • Set TS_Shadow_Move_TPL
There might be some more points, but this should be enough for next update. :csmile:
 
Replied to you in the quote.
Some notes:

Dark Helper:

Create a config trigger, which should include:
-Variable for DummyUnit
- Nope.
-
Variable for the spell's duration
- Easy enough to change so nope.
-
Variable for the Special Effect
- Yet again there is no point.

  • Set TempUnit = (Triggering unit)
  • Set TempPlayer = (Owner of TempUnit)
  • Set TempPoint2 = (Position of TempUnit)
-->
  • Set TempPlayer = (Triggering Player)
  • Set TempPoint2 = (Position of (Triggering unit))
  • Unit - Add a 5.00 second Generic expiration timer to (Last created unit)
  • Unit - Order (Last created unit) to Move To TempPoint
^Use the temp unit variable to gain performance.

Why do you nulling "TempUnit"? In next cast it gets a new value again.
There is never a need to null players, doesn't matter they are global or local. They are constant and never get destroyed/removed.
Null the local effect in and of trigger.

I feel better nulling players and it feels more proper.
:thumbs_up:

Change the variable and object data names for an easy identification towards the spell: prefix_Name

Shadow Move:


  • Set TS_Shadow_Move_TPL[TS_shadowindex] = (Owner of TS_Shadow_Move_TUOABC[TS_shadowindex])
-->
Set TS_Shadow_Move_TPL[TS_shadowindex] = (Triggering Player))

The ITE where you check to turn off the loop trigger should be moved into the deindex part.

Kay.

"Invulnerable (Neutral)" should be binded to the spell custom spells, as it can cause bugs since the user also might add this ability to any unit without using this system.

I don't get what you meant by this and it should never bug.

  • (Random integer number between 1 and 2) Equal to 1
^You can replace this by a boolean[index] which you always change between true/false to gain performance.
If true you create a special effect and set it "false". Else you just set it "true".

Nope, that would be rather useless creating an extra variable....

AttackType and DamageType should be configurable.

Probably...

Other units may block the caster, so it will never reach the targeted unit. Fix this, please.

Just did, have to upload new version though still.

So variable names should be improved. A name should say something about the intention of the variable.
For example, I would never know what following variables should represent, if I would not see the input:
  • Set TS_Shadow_Move_CU
  • Set TS_Shadow_Move_TUOABC
  • Set TS_Shadow_Move_TPL
There might be some more points, but this should be enough for next update. :csmile:

Yeah... you can thank LITHUFFIN for the lovely naming. :grin:

I'll see what I can do about most of your points otherwise what I said nope to won't change.
 
DarkHelper:
  • Import instructions are missing.
  • Make a short config trigger.
  • No need of locals.
  • I don't like the duration is hardcoded to 5 seconds. You are not independant from user's settings in gameplay constants. (duration of removing effects)
    You could make the "aim" visuals a unit for better controling, or just completly remove the effect.
  • Your nullings are not needed.
The DarkHelper spell is too simple in my eyes. The most work is done in ObjectEditor. You only create a pre-edited unit and order it to move to a point with offset.
I don't know if it's worth to update it without enhancing the concept, as it's very simple at the moment. :/

ShadowMove:
  • When units are between caster and target the spell fails. Fix this.
  • In deindex part only remove the invulnerability ability if the unit did not have it before casting.
  • Seperate the effect for caster and damage effect. User might want to differ them.
  • Your If/Then/Else block where you check for target's invulnerability doesn't make sense.
    1. Collision of units does have nothing todo with invulnerability.
    2. Why do you remove invulnerability from target? The user obvisouly want the unit to be invulnerabile.
    3. You never add invulnerability to target again, even it was removed. -> Affecs gameplay in a negative way.
  • Check for turning off the loop should be in deindex part.
  • Damage- and attack type should be configurable.
  • Add import instructions.

With these updates it's on a good way. :csmile:
 
Dark Helper

  • You can see the peon icon, when dummy is not moving. Remove it.
  • Make it support multiple levels.
  • The dummy should be set in config part.
  • Duration should be set in config part. (with support of level instanceability)
    Duration "5" is not 5 seconds as people might think but actually 5*interval. (0.031200)
    It should be duration in seconds. Also you might have wanted "0.0312500" as interval instead.
  • No need to null player variables. If you want you can completly remove the player variable, as you only use it once.
    No performance is won with that.
  • In loop you only remove units/effects and deindex them dynamicly.
    With a trick I believe you completly can remove the loop trigger.
    Instead of attaching effects to your dummy units, you can change the dummy model path to the effect.
    So yes, you would need an other dummy unit, as you currently use two different effects.
    But then when spell is casted, you only have to use the "Start expiration timer" for the dummy units with a certain duration,
    and it will kill the dummy (effects) automatically, without any kind of indexing/deindexing.
    Though you have to change the dummies' death type to "can't raise, won't decay",
    so they will be automatically removed from game after death.

ShadowMove

  • Make it support multiple levels.
  • Needs more configuration. All like damage/duration should be in config part.
    • Set DatOriginallyInvulCheck[TS_shadowloop] = False
    ^This is not needed onDeindex.
  • Still... What's about this invul add/remove to target thing? It seems strange to me. Why you damage invul units? How is it related to collison and to ownership?

The file's name is "Dat Shadow Move". Shadow Move is only one of two spells right now.
Also a version number would be helpful.

"JESP" is not correct under the field "category" in spell description.
 
Top