Tinki3
Special Member
- Reaction score
- 418
Making a DotA like Omnislash
What is Omnislash?
Omnislash is defined as "All-slash", an ability/move/special attack based on the original from Final Fantasy VII on Playstation One.
All-slash is defined as blinking around multiple enemy targets, dealing damage to each.
During each blink, the caster will have a special effect created somewhere on their body to make the spell look more convincing, or to make it look like they are moving extremely quickly. They will have their 'attack' animation played also to look convincing.
The Omnislasher becomes invulnerable during the ordeal, and is then made vulnerable after they finish slashing.
Introduction
I have made this tutorial for people who wanted an ability like Omnislash in their maps because it's one of the coolest spells in DotA. So, have you ever wondered how the heck DotA's Omnislash works? Well, here you can read how to make your own that is similar to DotA's to put in your map, or to use just for fun. Please note that if you want to succeed in making this spell, you need to have some skill with using GUI and knowing how to use variables (A good variable tutorial is located here). Without a decent amount of knowledge, you will waste your time reading this Tutorial. The Omnislash we are going to learn to make is going to be very similar to DotA's one. It will be easy, if you follow the steps one by one, and read most things that need to be read.
Contents:
1. Starting off
2. The first part of the trigger
3. The spell's basic mechanics
4. Creating an advanced loop for Omnislash - Part 1
5. Creating an advanced loop for Omnislash - Part 2
6. The final trigger
------------------------------------------------------------
1: Starting off
First of all, to get going, we need to base our spell of some ability.
I am going to use Storm Bolt in this case, as its a good, easy-to-modify, targetable spell, which is what we need.
Open the Object Editor, create a new spell, basing it off Storm Bolt, then rename it to 'Omnislash' and make it stun for 0.01 seconds at all levels (0.00 seconds will result in a permanent stun), as no stun is needed for Omnislash. Also, make it deal no damage at all at any level and delete the missile art.
After you have done all of that, add the ability to the Orc Blademaster, or some unit with a large sword.
------------------------------------------------------------
2: The first part of the trigger
Our next step is to start the triggering for the spell:
Create a new trigger and call it Omnislash. Then, add in the classic event - 'A unit Starts the effect of an ability' and the Ability comparison condition as shown below:
Code:
Omnislash
Events
Unit - A unit Starts the effect of an ability
Conditions
(Ability being cast) Equal to Omnislash
Actions
We now need to set a number of variables.
'o' stands for Omnislasher,
't' stands for target,
'tl' stands for target location:
Code:
Actions
Set o = (Triggering unit)
Set t = (Target unit of ability being cast)
Set tl = (Position of t)
Well, to be honest with you, casting unit returns triggering unit, leaving triggering unit the faster, more efficient option.
Casting unit is just a general reference in this case, and should be avoided.
Next, we need to set the amount of loops/times the caster will be blinking, which we will be needing later on in the trigger, which is very important, using the 'If/then/else' function. I will explain what we will be using the loops for later on, but for now, you need to create an integer variable. Name it 'loops', or something that'll make it easy to reference. After you've done that, set loops into a few variables as shown:
(Notice that we are using values 1 less per lvl than DotA's Omnislash's loop times.
This is because 1 loop is deducted due to the caster blinking to the targeted target initally)
Code:
If ((Level of Omnislash for o) Equal to 1) then do (Set loops = 2) else do (Do nothing)
If ((Level of Omnislash for o) Equal to 2) then do (Set loops = 4) else do (Do nothing)
If ((Level of Omnislash for o) Equal to 3) then do (Set loops = 7) else do (Do nothing)
Code:
Omnislash
Events
Unit - A unit Starts the effect of an ability
Conditions
(Ability being cast) Equal to Omnislash
Actions
Set o = (Triggering unit)
Set t = (Target unit of ability being cast)
Set tl = (Position of t)
If ((Level of Omnislash for o) Equal to 1) then do (Set loops = 2) else do (Do nothing)
If ((Level of Omnislash for o) Equal to 2) then do (Set loops = 4) else do (Do nothing)
If ((Level of Omnislash for o) Equal to 3) then do (Set loops = 7) else do (Do nothing)
------------------------------------------------------------
3: The spell's basic mechanics
After initializing our trigger for Omnislash, we need to know how Omnislash actually works, or, in other words, what mechanics it uses to do what it does.
First of all, DotA's Omnislash does NOT pause the caster (pausing basically makes a unit disabled). This is becuase it makes the entire spell run a whole lot better, as the caster is free to physically attack the target sometimes, thus if he has a critical strike ability, he has a chance to fire that which makes the spell actually look alot cooler, and improves it somewhat for us. So, instead of pausing the caster so he can't be controlled whilst he is Omnislashing, it uses a simple function called 'de-selecting' to remove the caster from selection for the owner of the caster so that he can't be moved AS easily. But, it still shouldn't be a problem, becuase, later on, we will be removing the caster, 'o' from selection every 0.3 seconds of game time, which will prove to be an interval too short to control a unit properly with.
When the caster 'attacks' his targets, he is instantly moved to their current location (as all DotA players would've seen), he then has his 'attack' animation played with SFX (Special effects) created on his chest for a bit of eye candy (note that he is also made 50% transparent when the spell is first casted). He is also made invulnerable so he can't be interupted by an enemy unit attacking him, either with physical damage, or a spell.
As for the damage that Omnislash does, the caster actually deals a random real number between 150 & 250 damage to the target. This makes the damage more random, and is what's used in DotA's Omnislash's trigger's damage, so since we're making a DotA-like Omnislash, why not do the same?
Let's start creating the part of Omnislash where the caster is made invulerable, is moved instantly to the target location (tl), plays his attack animation, creates SFX, and deals damage (note that he is also removed from selection when he first moves to the 'tl').
Let's add all of this into our trigger:
Code:
Unit - Make o Invulnerable
Code:
Animation - Change o's vertex coloring to (100.00%, 100.00%, 100.00%) with 50.00% transparency
Code:
Selection - Remove o from selection
Code:
Unit - Move o instantly to tl
Code:
Custom script: call RemoveLocation(udg_tl)
Code:
Animation - Play o's attack animation
Code:
Unit - Cause o to damage t, dealing (Random real number between 150.00 and 250.00) damage of attack type Hero and damage type Normal
Code:
Special Effect - Create a special effect attached to the chest of o using Abilities\Spells\NightElf\Blink\BlinkCaster.mdl
Code:
Special Effect - Destroy (Last created special effect)
All of this should've been completed so far:
Code:
Omnislash
Events
Unit - A unit Starts the effect of an ability
Conditions
(Ability being cast) Equal to Omnislash
Actions
Set o = (Triggering unit)
Set t = (Target unit of ability being cast)
Set tl = (Position of t)
If ((Level of Omnislash for o) Equal to 1) then do (Set loops = 2) else do (Do nothing)
If ((Level of Omnislash for o) Equal to 2) then do (Set loops = 4) else do (Do nothing)
If ((Level of Omnislash for o) Equal to 3) then do (Set loops = 7) else do (Do nothing)
Unit - Make o Invulnerable
Animation - Change o's vertex coloring to (100.00%, 100.00%, 100.00%) with 50.00% transparency
Selection - Remove o from selection
Unit - Move o instantly to tl
Custom script: call RemoveLocation(udg_tl)
Animation - Play o's attack animation
Unit - Cause o to damage t, dealing (Random real number between 150.00 and 250.00) damage of attack type Hero and damage type Normal
Special Effect - Create a special effect attached to the chest of o using Abilities\Spells\NightElf\Blink\BlinkCaster.mdl
Special Effect - Destroy (Last created special effect)
------------------------------------------------------------
4: Creating an advanced loop for Omnislash - Part 1
In order to make the caster blink around random targets over & over, we need to make a long and advanced loop that will make sure our caster actually does blink around to random targets, and to tell the trigger to stop temporarially Omnislashing or not. It will take a fair amount of time to complete this loop, but, once its done, our Omnislash trigger will be more or less 99% complete.
To create a loop, we will be using the function, For Each Integer A, Do Multiple Actions.
Select this function from the actions list (located near the top), and add it to the very bottom of your trigger. Then you need to change it around by doing this (note that loops is the variable we set earlier):
Code:
For each (Integer A) from 1 to [COLOR="Red"]loops[/COLOR], do (Actions)
Loop - Actions
Next, we need to add in a wait of 0.30 game-time seconds. This will give us a good delay between each attack made to targets.
Note that 0.27 seconds is the minimal amount of delay a wait can have, so 0.3 seems to be the nicest value to use here.
Add that into the Loop-Actions:
Code:
For each (Integer A) from 1 to loops, do (Actions)
Loop - Actions
Wait 0.30 game-time seconds
select 'o' from the variable list.
You should have done all of the following so far:
Code:
Omnislash
Events
Unit - A unit Starts the effect of an ability
Conditions
(Ability being cast) Equal to Omnislash
Actions
Set o = (Triggering unit)
Set t = (Target unit of ability being cast)
Set tl = (Position of t)
If ((Level of Omnislash for o) Equal to 1) then do (Set loops = 2) else do (Do nothing)
If ((Level of Omnislash for o) Equal to 2) then do (Set loops = 4) else do (Do nothing)
If ((Level of Omnislash for o) Equal to 3) then do (Set loops = 7) else do (Do nothing)
Unit - Make o Invulnerable
Animation - Change o's vertex coloring to (100.00%, 100.00%, 100.00%) with 50.00% transparency
Selection - Remove o from selection
Unit - Move o instantly to tl
Custom script: call RemoveLocation(udg_tl)
Animation - Play o's attack animation
Unit - Cause o to damage t, dealing (Random real number between 150.00 and 250.00) damage of attack type Hero and damage type Normal
Special Effect - Create a special effect attached to the chest of o using Abilities\Spells\NightElf\Blink\BlinkCaster.mdl
Special Effect - Destroy (Last created special effect)
For each (Integer A) from 1 to loops, do (Actions)
Loop - Actions
Wait 0.30 game-time seconds
Set o_current_loc = (Position of o)
Open up the variable editor and create a new 'Unit Group' variable, with an array size of 1, and change it's name to 'EG' (Enemy Group, for short).
Set the first EG variable (EG[1]) into your trigger below the 'o_current_loc', like so:
Code:
Set EG[1] = (Units within 600.00 of o_current_loc matching ((((Matching unit) is A structure) Not equal to True) and ((((Matching unit) is alive) Equal to True) and ((((Matching unit) belongs to an enemy of (Owner of o)) Equal to True) and ((((Matching unit) is A flying unit) Not equal to True) and ((((Matching unit) is sleeping) Not equal to True) and (((Matching unit) is Magic Immune) Not equal to True) and (((Matching unit) is hidden) Note equal to True)
-Not structures/buildings
-Not dead
-Enemies of 'o'
-Not flying units
-Not sleeping
-Not magic immune
-Not hidden
All of that seems more than logical to me, as it should to you.
After you have set EG[1], its time to set EG[2]. EG[2] will pick a random unit from EG[1] to ensure us that 'o' only attacks 1 of them, not the whole group, as that would look very strange indeed:
Code:
Set EG[2] = (Random 1 units from EG[1])
Notice that 'o_current_loc' is still sitting there, doing nothing, so we may as well remove it with a custom script, to avoid yet another memory leak, as have no use for it again:
Code:
Custom script: call RemoveLocation(udg_o_current_loc)
Code:
Omnislash
Events
Unit - A unit Starts the effect of an ability
Conditions
(Ability being cast) Equal to Omnislash
Actions
Set o = (Triggering unit)
Set t = (Target unit of ability being cast)
Set tl = (Position of t)
If ((Level of Omnislash for o) Equal to 1) then do (Set loops = 2) else do (Do nothing)
If ((Level of Omnislash for o) Equal to 2) then do (Set loops = 4) else do (Do nothing)
If ((Level of Omnislash for o) Equal to 3) then do (Set loops = 7) else do (Do nothing)
Unit - Make o Invulnerable
Animation - Change o's vertex coloring to (100.00%, 100.00%, 100.00%) with 50.00% transparency
Selection - Remove o from selection
Unit - Move o instantly to tl
Custom script: call RemoveLocation(udg_tl)
Animation - Play o's attack animation
Unit - Cause o to damage t, dealing (Random real number between 150.00 and 250.00) damage of attack type Hero and damage type Normal
Special Effect - Create a special effect attached to the chest of o using Abilities\Spells\NightElf\Blink\BlinkCaster.mdl
Special Effect - Destroy (Last created special effect)
For each (Integer A) from 1 to loops, do (Actions)
Loop - Actions
Wait 0.30 game-time seconds
Set o_current_loc = (Position of o)
Set EG[1] = (Units within 600.00 of o_current_loc matching ((((Matching unit) is A structure) Not equal to True) and ((((Matching unit) is alive) Equal to True) and ((((Matching unit) belongs to an enemy of (Owner of o)) Equal to True) and ((((Matching unit) is A flying
Set EG[2] = (Random 1 units from EG[1])
Custom script: call RemoveLocation(udg_o_current_loc)
5: Creating an advanced loop for Omnislash - Part 2
After creating our massively piled up Unit Group, EG[1] and [2], we now need to make 'o' attack units from EG[2].
We will be needing to use the function If/Then/Else, Multiple Functions in our loop for a number of reasons:
It will ensure us that if the amount of units that are in the EG[1] is greater than 0, in other words, not equal to 0, it will pick every unit in EG[2] and do our usual mechanics. And if the number of units in EG[1] are not greater than 0, it will make 'o', the caster, non-transparent and turned back to being vulnerable again.
Add the following into your Omnislash trigger:
Code:
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
If - Conditions
(Number of units in EG[1]) Greater than 0
Then - Actions
Unit Group - Pick every unit in EG[2] and do (Actions)
Loop - Actions
Else - Actions
After doing all of that, you need to create 2 more variables. Create a new unit variable called p and another point variable called pl, and set them into the Loop-Actions of the Unit Group as shown:
Code:
Unit Group - Pick every unit in EG[2] and do (Actions)
Loop - Actions
Set p = (Picked unit)
Set pl = (Position of p)
You should end up with this:
Code:
Unit Group - Pick every unit in EG[2] and do (Actions)
Loop - Actions
Set p = (Picked unit)
Set pl = (Position of p)
Selection - Remove o from selection
Unit - Move o instantly to pl
Custom script: call RemoveLocation(udg_pl)
Animation - Play o's attack animation
Unit - Cause o to damage p, dealing (Random real number between 150.00 and 250.00) damage of attack type Hero and damage type Normal
Special Effect - Create a special effect attached to the chest of o using Abilities\Spells\NightElf\Blink\BlinkCaster.mdl
Special Effect - Destroy (Last created special effect)
Code:
Unit Group - Pick every unit in EG[2] and do (Actions)
Loop - Actions
Set p = (Picked unit)
Set pl = (Position of p)
Selection - Remove o from selection
Unit - Move o instantly to pl
Custom script: call RemoveLocation(udg_pl)
Animation - Play o's attack animation
Unit - Cause o to damage p, dealing (Random real number between 150.00 and 250.00) damage of attack type Hero and damage type Normal
Special Effect - Create a special effect attached to the chest of o using Abilities\Spells\NightElf\Blink\BlinkCaster.mdl
Special Effect - Destroy (Last created special effect)
Custom script: call DestroyGroup(udg_EG[1])
Custom script: call DestroyGroup(udg_EG[2])
Code:
Else - Actions
Custom script: call DestroyGroup(udg_EG[1])
Custom script: call DestroyGroup(udg_EG[2])
Selection - Add o to selection for (Owner of o)
Animation - Change o's vertex coloring to (100.00%, 100.00%, 100.00%) with 0.00% transparency
Unit - Make o Vulnerable
Omnislash 99% complete:
(see how we use our set 'loops' to determine how many times the loop is looped).
Code:
Omnislash
Events
Unit - A unit Starts the effect of an ability
Conditions
(Ability being cast) Equal to Omnislash
Actions
Set o = (Triggering unit)
Set t = (Target unit of ability being cast)
Set tl = (Position of t)
If ((Level of Omnislash for o) Equal to 1) then do (Set loops = 2) else do (Do nothing)
If ((Level of Omnislash for o) Equal to 2) then do (Set loops = 4) else do (Do nothing)
If ((Level of Omnislash for o) Equal to 3) then do (Set loops = 7) else do (Do nothing)
Unit - Make o Invulnerable
Animation - Change o's vertex coloring to (100.00%, 100.00%, 100.00%) with 50.00% transparency
Selection - Remove o from selection
Unit - Move o instantly to tl
Custom script: call RemoveLocation(udg_tl)
Animation - Play o's attack animation
Unit - Cause o to damage t, dealing (Random real number between 150.00 and 250.00) damage of attack type Hero and damage type Normal
Special Effect - Create a special effect attached to the chest of o using Abilities\Spells\NightElf\Blink\BlinkCaster.mdl
Special Effect - Destroy (Last created special effect)
For each (Integer A) from 1 to loops, do (Actions)
Loop - Actions
Wait 0.30 game-time seconds
Set o_current_loc = (Position of o)
Set EG[1] = (Units within 600.00 of o_current_loc matching ((((Matching unit) is A structure) Not equal to True) and ((((Matching unit) is alive) Equal to True) and ((((Matching unit) belongs to an enemy of (Owner of o)) Equal to True) and ((((Matching unit) is A flying
Set EG[2] = (Random 1 units from EG[1])
Custom script: call RemoveLocation(udg_o_current_loc)
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
If - Conditions
(Number of units in EG[1]) Greater than 0
Then - Actions
Unit Group - Pick every unit in EG[2] and do (Actions)
Loop - Actions
Set p = (Picked unit)
Set pl = (Position of p)
Selection - Remove o from selection
Unit - Move o instantly to pl
Custom script: call RemoveLocation(udg_pl)
Animation - Play o's attack animation
Unit - Cause o to damage p, dealing (Random real number between 150.00 and 250.00) damage of attack type Hero and damage type Normal
Special Effect - Create a special effect attached to the chest of o using Abilities\Spells\NightElf\Blink\BlinkCaster.mdl
Special Effect - Destroy (Last created special effect)
Custom script: call DestroyGroup(udg_EG[1])
Custom script: call DestroyGroup(udg_EG[2])
Else - Actions
Custom script: call DestroyGroup(udg_EG[1])
Custom script: call DestroyGroup(udg_EG[2])
Selection - Add o to selection for (Owner of o)
Animation - Change o's vertex coloring to (100.00%, 100.00%, 100.00%) with 0.00% transparency
Unit - Make o Vulnerable
6: The final trigger
A few final tweeks need to be added to the trigger to make sure it resets o's stats. Add the following to your trigger to ensure this:
Code:
Selection - Add o to selection for (Owner of o)
Animation - Change o's vertex coloring to (100.00%, 100.00%, 100.00%) with 0.00% transparency
Unit - Make o Vulnerable
Here is the final result for the trigger for Omnislash:
Code:
Omnislash
Events
Unit - A unit Starts the effect of an ability
Conditions
(Ability being cast) Equal to Omnislash
Actions
Set o = (Triggering unit)
Set t = (Target unit of ability being cast)
Set tl = (Position of t)
If ((Level of Omnislash for o) Equal to 1) then do (Set loops = 2) else do (Do nothing)
If ((Level of Omnislash for o) Equal to 2) then do (Set loops = 4) else do (Do nothing)
If ((Level of Omnislash for o) Equal to 3) then do (Set loops = 7) else do (Do nothing)
Unit - Make o Invulnerable
Animation - Change o's vertex coloring to (100.00%, 100.00%, 100.00%) with 50.00% transparency
Selection - Remove o from selection
Unit - Move o instantly to tl
Custom script: call RemoveLocation(udg_tl)
Animation - Play o's attack animation
Unit - Cause o to damage t, dealing (Random real number between 150.00 and 250.00) damage of attack type Hero and damage type Normal
Special Effect - Create a special effect attached to the chest of o using Abilities\Spells\NightElf\Blink\BlinkCaster.mdl
Special Effect - Destroy (Last created special effect)
For each (Integer A) from 1 to loops, do (Actions)
Loop - Actions
Wait 0.30 game-time seconds
Set o_current_loc = (Position of o)
Set EG[1] = (Units within 600.00 of o_current_loc matching ((((Matching unit) is A structure) Not equal to True) and ((((Matching unit) is alive) Equal to True) and ((((Matching unit) belongs to an enemy of (Owner of o)) Equal to True) and ((((Matching unit) is A flying
Set EG[2] = (Random 1 units from EG[1])
Custom script: call RemoveLocation(udg_o_current_loc)
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
If - Conditions
(Number of units in EG[1]) Greater than 0
Then - Actions
Unit Group - Pick every unit in EG[2] and do (Actions)
Loop - Actions
Set p = (Picked unit)
Set pl = (Position of p)
Selection - Remove o from selection
Unit - Move o instantly to pl
Custom script: call RemoveLocation(udg_pl)
Animation - Play o's attack animation
Unit - Cause o to damage p, dealing (Random real number between 150.00 and 250.00) damage of attack type Hero and damage type Normal
Special Effect - Create a special effect attached to the chest of o using Abilities\Spells\NightElf\Blink\BlinkCaster.mdl
Special Effect - Destroy (Last created special effect)
Custom script: call DestroyGroup(udg_EG[1])
Custom script: call DestroyGroup(udg_EG[2])
Else - Actions
Custom script: call DestroyGroup(udg_EG[1])
Custom script: call DestroyGroup(udg_EG[2])
Selection - Add o to selection for (Owner of o)
Animation - Change o's vertex coloring to (100.00%, 100.00%, 100.00%) with 0.00% transparency
Unit - Make o Vulnerable
Selection - Add o to selection for (Owner of o)
Animation - Change o's vertex coloring to (100.00%, 100.00%, 100.00%) with 0.00% transparency
Unit - Make o Vulnerable
Have fun Omnislashing!