You could store the level of ability being cast into a variable since you're calling it three times. Not a big deal though.
Save the handle into a variable as mentioned.
I also agree that you should set all the configurables into variables in the init trigger, like base damage, bonus damage per ability level, AoE etc.
OB_Clean shouldn't be on all the time.
The learn tooltip image is missing.
The follow though time is too short for the unit to complete the animation, set it to about 1 second or something like that.
The dummy doesn't need invulnerability ability, is has locust.
I'd set the dummy to can't raise, does not decay. And not remove it with Unit - remove unit from game.
This should be done only when you reduce obcounter, it can't be zero during other loops:
-
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
-

If - Conditions
-


OB_Counter Less than or equal to 0
-

Then - Actions
-


Trigger - Turn off (This trigger)
-

Else - Actions
You can replace (Owner of(unit)) with triggering player in the cast trigger. It's slightly faster.
I recommend using bj_wantDestroyGroup for groups that you want to destroy immediately after use. Slightly better performance.
Last created hastable:
-
(Load 10 of (Key (Picked unit)) from OB_Hash) Less than (Load 3 of (Key (Load 1 of (Key (Picked unit)) in OB_Hash)) from (Last created hashtable))