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

Voodoo

Status
Not open for further replies.
Level 16
Joined
Jul 31, 2012
Messages
2,217
Make a dummy unit channel it.

And make him move to the location of the caster with:
SetUnitX(x) and SetUnitY(y)

like this:
  • Cast
  • Events -
    • Unit - A Unit starts the effect of an ability
  • Conditions -
    • (Ability being Cast) equal to your ability
  • Actions -
    • Set BBV_I = BBV_I + 1
    • Set temp_loc = Postion of (Triggering Unit)
    • Unit - Create 1 dummy at temp_loc facing 0.00 degrees
    • Set BBV_U[BBV_I] = (Last Created Unit)
    • Unit - Order BBV_U[BBV_I] to BigBadVoodoo
    • Unit - Add (Spell Duration) to BBV_U[BBV_I]
    • Trigger - Turn On (Loop)
    • Custom script: call RemoveLocation(udg_temp_loc)
    • set BBV_C[BBV_I] = (Triggering Unit)
    • Set BBV_B[BBV_I] = True
    • Unit - Make BBV_C[BBV_I] Invulnerable
  • Loop
  • Events -
    • Time - every 0.03 of game time
  • Conditions -
  • Actions -
    • Set temp_Int = BBV_I
    • For Each integer BBV_II from 1 to BBV_I do actions
      • loop -
        • if then else
          • if -
            • ( ((BBV_U[BBV_II] is Dead) equal to true) Or ((BBV_B[BBV_II]) equal to false)
          • then
            • Set BBV_B[BBV_II] = false
            • Set temp_Int = temp_Int - 1
            • Unit - Make BBV_C[BBV_II] Vulnerable
          • else
            • Set temp_loc = Postion of BBV_C[BBV_II]
            • Custom script: SetUnitX(udg_BBV_U[BBV_II], GetLocationX(udg_temp_loc)
            • Custom script: SetUnitY(udg_BBV_U[BBV_II], GetLocationY(udg_temp_loc)
    • if then else
      • if -
        • (temp_Int) equal to 0
      • then
        • Set BBV_I = 0
        • Trigger - Turn Off (This Trigger)
        • else
 
Level 3
Joined
Sep 7, 2013
Messages
40
However that will give up it's only weakness - even the hero who casts it will be invulnerable, as the caster in this case would ultimately be a dummy unit.

The duration's being significantly reduced to compensate. Ten seconds at the moment. Thanks!
 
Level 22
Joined
Aug 27, 2013
Messages
3,973
@Jad congrats! That invulnerability will last for 0.03 seconds, or will actually never happen. You don't have a counter. Nor expiration timer.
lol?
he use expiration to dummy
make triggering unit invulnerable
boolean equal to true
if dummy is dead or boolean equal to false
make boolean equal to false
make triggering unit vulnerable
but if dummy is alive or boolean equal to true
the dummy will move to triggering unit's location

except, you did try this and this is not complete (i guess he makes this in a hurry)
he doesn't recycle them properly
 
Level 25
Joined
Sep 26, 2009
Messages
2,378
  • Cast
  • Events -
    • Unit - A Unit starts the effect of an ability
  • Conditions -
    • (Ability being Cast) equal to your ability
  • Actions -
    • Set BBV_I = BBV_I + 1
    • Set temp_loc = Postion of (Triggering Unit)
    • Unit - Create 1 dummy at temp_loc facing 0.00 degrees
    • Set BBV_U[BBV_I] = (Last Created Unit)
    • Unit - Order BBV_U[BBV_I] to BigBadVoodoo
    • Unit - Add (Spell Duration) to BBV_U[BBV_I]
    • Trigger - Turn On (Loop)
    • Custom script: call RemoveLocation(udg_temp_loc)
    • set BBV_C[BBV_I] = (Triggering Unit)
    • Set BBV_B[BBV_I] = True
    • Unit - Make BBV_C[BBV_I] Invulnerable
  • Loop
  • Events -
    • Time - every 0.03 of game time
  • Conditions -
  • Actions -
    • Set temp_Int = BBV_I
    • For Each integer BBV_II from 1 to BBV_I do actions
      • loop -
        • if then else
          • if -
            • ( ((BBV_U[BBV_II] is Dead) equal to true) Or ((BBV_B[BBV_II]) equal to false)
          • then
            • Set BBV_B[BBV_II] = false
            • Set temp_Int = temp_Int - 1
            • Unit - Make BBV_C[BBV_II] Vulnerable
          • else
            • Set temp_loc = Postion of BBV_C[BBV_II]
            • Custom script: SetUnitX(udg_BBV_U[BBV_II], GetLocationX(udg_temp_loc)
            • Custom script: SetUnitY(udg_BBV_U[BBV_II], GetLocationY(udg_temp_loc)
    • if then else
      • if -
        • (temp_Int) equal to 0
      • then
        • Set BBV_I = 0
        • Trigger - Turn Off (This Trigger)
        • else
This is very badly handled.

In the "cast" trigger:
1) it's better to save the caster first into caster_variable, then save position of the caster_variable. Right now, the first trigger makes 2 (Triggering unit) function calls, while only one can be made instead.
2) Now I'm unsure, since I didn't test this myself, but in one of the other threads, there was a problem with dummy unit not casting an ability, when it was first ordered to cast the ability and then an expiration timer was given to it. It was, afaik, fixed by swapping those 2 actions.
3) There is no need to even save the triggering unit into variable and make it invulnerable, since the spell itself does that - it won't make invulnerable only the dummy unit which is actually the one casting it, however that dummy unit has locust already.
4) You don't need the boolean BBV_B, since it serves no purpose.
5) Afaik, it's better to first check if a trigger is already on or not, before switching it on.

In the "loop" trigger
1) First off, this trigger will never switch off, until all instances of the spell have ended - this is terrible efficiency-wise.
2) There is no need for Temp_int variable. You need to check the actual BBV_I variable, which handles indexes. It is exactly because of the different values of both Temp_Int and BBV_I and then setting them to same value at the start of the loop trigger why this trigger won't turn off until all instances have ended.
3) There is no need for a specific BBV_II integer variable used in the Loop - it's better to have one integer variable used for all integer Loops. You would only need another integer variable for loop if you made a loop inside loop - e.g. this:
  • For each (Integer LoopA) from 1 to 3, do (Actions)
    • Loop - Actions
      • For each (Integer LoopB) from 1 to 5, do (Actions)
        • Loop - Actions
4) The ITE is also badly handled. Why check if boolean is set to "False" if the "Then" action sets this boolean to "false"? The boolean is completely unneeded there. What you need to do is to check if the dummy is dead. If it's really dead, deindex the whole thing.
5) The loop trigger leaks point "temp_loc", as it is never destroyed there.
6) The last ITE should not check temp_int, as it is not definite, it should check BBV_I instead.
 
Level 22
Joined
Aug 27, 2013
Messages
3,973
haha, i'm right :p

anyway.. i'll fix that ASAP

Edit: Here they are


  • Voodoo
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Big Bad Voodoo
    • Actions
      • Set Max_Index = (Max_Index + 1)
      • Set Caster[Max_Index] = (Triggering unit)
      • Set TempPoint = (Position of Caster[Max_Index])
      • Unit - Create 1 Dummy for (Owner of Caster[Max_Index]) at TempPoint facing Default building facing degrees
      • Set Dummy[Max_Index] = (Last created unit)
      • Unit - Add a 10.00 second Generic expiration timer to Dummy[Max_Index]
      • Unit - Order Dummy[Max_Index] to Orc Shadow Hunter - Big Bad Voodoo
      • Custom script: call RemoveLocation(udg_TempPoint)
      • Unit - Make Caster[Max_Index] Invulnerable
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • Max_Index Equal to 1
        • Then - Actions
          • Trigger - Turn on Voodoo Loop <gen>
        • Else - Actions
  • Voodoo Loop
    • Events
      • Time - Every 0.03 seconds of game time
    • Conditions
    • Actions
      • For each (Integer Current_Index) from 1 to Max_Index, do (Actions)
        • Loop - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (Dummy[Current_Index] is dead) Equal to True
            • Then - Actions
              • Unit - Make Caster[Current_Index] Vulnerable
              • Set Caster[Current_Index] = Caster[Max_Index]
              • Set Caster[Max_Index] = No unit
              • Set Dummy[Current_Index] = Dummy[Max_Index]
              • Set Dummy[Max_Index] = No unit
              • Set Current_Index = (Current_Index - 1)
              • Set Max_Index = (Max_Index - 1)
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • Max_Index Equal to 0
                • Then - Actions
                  • Trigger - Turn off (This trigger)
                • Else - Actions
            • Else - Actions
              • Custom script: call SetUnitX(udg_Dummy[udg_Current_Index], GetUnitX(udg_Caster[udg_Current_Index])
              • Custom script: call SetUnitY(udg_Dummy[udg_Current_Index], GetUnitY(udg_Caster[udg_Current_Index])
Note: I've been fixing this triggers four time or so >.>, tell me if there is something wrong again
 
Last edited:
Level 13
Joined
Mar 24, 2013
Messages
1,105
Make sure you actually order the dummy to cast Big Bad Voodoo, and I don't think you need to make the caster in/vulnerable as the spell does this on its own.

If you move instantly, it will cancel the channeling.


  • Custom script: call SetUnitX(udg_Dummy[udg_Current_Index], GetUnitX(udg_Caster[udg_Current_Index]))
  • Custom script: call SetUnitY(udg_Dummy[udg_Current_Index], GetUnitY(udg_Caster[udg_Current_Index]))
Also you no longer need TempPoint
 
Last edited:
Level 13
Joined
Mar 24, 2013
Messages
1,105
Not to be nit picky, but just so its golden, in the SetX/Y I originally forgot the underscore between Current_Index. So it will throw an error that the variable doesn't exist. So just from udg_CurrentIndex => udg_Current_Index
 
Status
Not open for further replies.
Top