private constant integer SpellID = 'A000'
It doesn't have to be based on Trueshot, though, as a matter of fact having the buff is actually very ugly for such a passive. I think it would be much better and less confusing to users the less they have
to configure. Base it on evasion with 0% or something like that.
private function GetUnitsAngle takes unit a, unit b returns real
return Atan2(GetUnitY(b)-GetUnitY(a), GetUnitX(b)-GetUnitX(a))
Man, inline that call wherever you use it and save the lines of code.
set Cindexes[Cindex] = integer(C)
That typecast isn't necessary, structs are integers anyways.
set SonicFX = GetAbilityEffectById(SpellID, EFFECT_TYPE_SPECIAL, 0)
set BloodFX = GetAbilityEffectById(SpellID, EFFECT_TYPE_SPECIAL, 1)
Make these into configurable strings so people can change the path as normal. It's not totally intuitive how someone would change the effects right now, so this change is pretty important.
Whoa, man, what are you doing? Go look at how I re-index things in Shrapnade, all of this looping stuff is horrendously inefficient. You could be saving all of these loops and everything. Simply put the ith indexed entry where this' indexed entry is upon removal. Easy, man. :p
private method onDestroy takes nothing returns nothing
call ForGroup(.Units, function Data.Release)
set .caster = null
set .dummy = null
The caster/dummy vars are re-used globals in arrays, they don't need to be nulled if you properly clean up the rest of it. (Which you do)
call DestroyEffect(AddSpecialEffectTarget(BloodFX, GetEnumUnit(), "chest"))
Needs to be configurable where to attach the effects.
if IsUnitInRangeXY(GetEnumUnit(), GetUnitX(D.dummy) + Radius * D.cos, GetUnitY(D.dummy) + Radius * D.sin, Radius) and not IsUnitInGroup(GetEnumUnit(), D.Units) then
This function internally uses distance math to return true or false, just do a (x2-x1)*(x2-x1)+(y2-y1)*(y2-y1)<= MaxDist*MaxDist mathematical check and save yourself that trouble. Also, don't be afraid to use local real variables, makes your code loads easier to read.
I'm not a big fan of the loop/search method to get the desired index of an array, there are cleaner ways of handling it. I won't be picky about it, though, since it won't be an issue until we're talking more than 30 or so instances at once.