{\rtf1\ansi\ansicpg1252\cocoartf949\cocoasubrtf270 {\fonttbl\f0\fnil\fcharset0 Monaco;} {\colortbl;\red255\green255\blue255;} \margl1440\margr1440\vieww28300\viewh16240\viewkind0 \pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ql\qnatural\pardirnatural \f0\fs22 \cf0 //*******************************************************************\ //* Spell Name: Flare *\ //* Spell Author: Pyrogasm *\ //* *\ //* Follows the JESP Standard *\ //* *\ //* Note: To change the "codename" of this spell you must replace *\ //* All instances of BOTH "Flare_" and "_Flare" *\ //*******************************************************************\ \ //*******************************************************************\ //* Start Configuration *\ //*******************************************************************\ \ constant function Flare_AbilityId takes nothing returns integer\ return 'A004'\ endfunction\ \ constant function Flare_BuffAbilityId takes nothing returns integer\ return 'A001'\ endfunction\ \ constant function Flare_NextPointAbilityId takes nothing returns integer\ return 'A005'\ endfunction\ \ constant function Flare_CancelDetectorAbilityId takes nothing returns integer\ return 'A003'\ endfunction\ \ constant function Flare_BuffId takes nothing returns integer\ return 'B000'\ endfunction\ \ constant function Flare_DummyUnitId takes nothing returns integer\ return 'h000' //Must have 0 cast point and cast backswing\ endfunction\ \ constant function Flare_EffectUnitId takes nothing returns integer\ return 'h002'\ endfunction\ \ constant function Flare_CancelDetectorOrderId takes nothing returns string\ return "taunt"\ endfunction\ \ constant function Flare_NextPointOrderId takes nothing returns string\ return "rainoffire"\ endfunction\ \ constant function Flare_BuffAbilityOrderId takes nothing returns string\ return "cripple"\ endfunction\ \ constant function Flare_NextPointHotkey takes nothing returns string\ return "j" //Always Lowercase\ endfunction\ \ constant function Flare_CancelDetectorHotkey takes nothing returns string\ return "l" //Always Lowercase\ endfunction\ \ constant function Flare_CastHotkeyPressDelay takes nothing returns real\ return 0.027 //It takes 1 frame of the game to update the UI for the ForceUIKey to work, so\ //This value must be the length of 1 frame or more, and that changes constantly.\ //The best you can do is guess... if the game is laggy this value will probably\ //Need to be higher.\ endfunction\ \ constant function Flare_CheckInterval takes nothing returns real\ return 0.075 //I wouldn't recommend anything lower than 0.06; it causes the spell to bug-out sometimes\ endfunction\ \ constant function Flare_EffectCreationInterval takes nothing returns real\ return 0.04\ endfunction\ \ constant function Flare_DamageTimerInterval takes nothing returns real\ return 0.04\ endfunction\ \ constant function Flare_ManaCost takes integer Level returns real\ return 75.00 //So that mana is properly refunded if the spell is canceled.\ endfunction\ \ constant function Flare_PointIndicatorEffect takes nothing returns string\ return "Objects\\\\InventoryItems\\\\BattleStandard\\\\BattleStandard.mdl"\ endfunction\ \ function Flare_NumberOfEffectsPerSegment takes integer Level, real Distance returns integer\ return R2I(Distance/25.00)\ endfunction\ \ function Flare_EffectUnitAnimationSpeed takes integer Level returns real\ return 5.00\ endfunction\ \ function Flare_DamagePerSecond takes integer Level, real Area returns real\ return (30.00+20.00*Level)/(Area*0.01*0.01*0.3) //Wc3 doesn't support precision at the 0.00003 level\ endfunction\ \ function Flare_DamageFilter takes unit Caster, unit FilterUnit, player CasterOwner, integer Level returns boolean\ return IsUnitEnemy(FilterUnit, CasterOwner) //(IsUnitType(FilterUnit, UNIT_TYPE_MAGIC_IMMUNE) == false) and \ endfunction\ \ constant function Flare_Duration takes integer Level returns real\ return 7.00\ endfunction\ \ //*******************************************************************\ //* End Configuration *\ //*******************************************************************\ \ function Flare_MainCastConditions takes nothing returns boolean\ return GetSpellAbilityId() == Flare_AbilityId()\ endfunction\ \ function Flare_NextPointCastConditions takes nothing returns boolean\ return (IsUnitInGroup(GetTriggerUnit(), GetAttachedGroup(gg_trg_Flare, "Flare_PlayerData_CastingUnits"))) and (GetIssuedOrderId() == OrderId(Flare_NextPointOrderId()))\ endfunction\ \ function Flare_CancelCastConditions takes nothing returns boolean\ if GetAttachedBoolean(GetTriggerUnit(), "Flare_NoDetect") then\ call AttachBoolean(GetTriggerUnit(), "Flare_NoDetect", false)\ return false\ endif\ \ return (GetSpellAbilityId() == Flare_CancelDetectorAbilityId()) and (IsUnitInGroup(GetTriggerUnit(), GetAttachedGroup(gg_trg_Flare, "Flare_PlayerData_CastingUnits")))\ endfunction\ \ function Flare_BuffFilter takes nothing returns boolean\ local unit Enum = GetEnumUnit()\ \ if not(IsUnitInGroup(Enum, bj_groupAddGroupDest)) and (GetUnitAbilityLevel(Enum, bj_meleeTwinkedHeroes[30]) > 0) then\ call UnitRemoveAbility(Enum, bj_meleeTwinkedHeroes[30])\ call BJDebugMsg("Removed Buff")\ endif\ \ set Enum = null\ return false\ endfunction\ \ function Flare_Filter takes nothing returns boolean\ return Flare_DamageFilter(bj_ghoul[28], GetFilterUnit(), bj_groupEnumOwningPlayer, bj_forceRandomConsidered)\ endfunction\ \ //*******************************************************************\ //* Start External *\ //*******************************************************************\ \ //====================================\ //GroupAddUnitsInTriangle by Vexorian\ // Slightly modified by Pyrogasm\ \ function GroupAddUnitsInTriangle_AngleCheck takes real angle, real angle1, real angle2, real PI2 returns boolean\ local real x\ if (angle1>angle2) then\ set x=angle1\ set angle1=angle2\ set angle2=x\ endif\ if (angle2-angle1>angle1 - (angle2-PI2)) then\ set angle2=angle2-PI2\ if (angle < bj_PI) then\ set angle=angle-PI2\ endif\ return (angle>=angle2) and (angle<=angle1)\ endif\ return (angle>=angle1) and (angle<=angle2)\ endfunction\ \ function GetRectThatLimitsTriangle takes real x1, real y1, real x2, real y2, real x3, real y3 returns rect\ local real maxx\ local real minx\ if (x1>x2) then\ if (x2>x3) then //x1>x2>x3\ set maxx=x1\ set minx=x3\ elseif (x3>x1) then //x3>x1>x2\ set maxx=x3\ set minx=x2\ else //x3>x1>x2\ set maxx=x1\ set minx=x2\ endif\ elseif (x1>x3) then //x2>x1>x3\ set maxx=x2\ set minx=x3\ elseif (x3>x2) then //x3>x2>x1\ set maxx=x3\ set minx=x1\ else //x2>x3>x1\ set maxx=x2\ set minx=x1\ endif\ \ if (y1>y2) then\ if (y2>y3) then //y1>y2>y3\ return Rect(minx,y3,maxx,y1)\ elseif (y3>y1) then //y3>y1>y2\ return Rect(minx,y2,maxx,y3)\ else //y3>y1>y2\ return Rect(minx,y2,maxx,y1)\ endif\ elseif (y1>y3) then //y2>y1>y3\ return Rect(minx,y3,maxx,y2)\ elseif (y3>y2) then //y3>y2>y1\ return Rect(minx,y1,maxx,y3)\ endif\ //y2>y3>y1\ return Rect(minx,y1,maxx,y2)\ endfunction\ \ function GroupAddUnitsInTriangle takes group whichGroup, real x1, real y1, real x2, real y2, real x3, real y3 returns nothing\ local rect semi=GetRectThatLimitsTriangle(x1,y1,x2,y2,x3,y3)\ local group inrect=CreateGroup()\ local unit picked\ local real x\ local real y\ local real alpha=Atan2(y2-y1,x2-x1)\ local real beta =Atan2(y3-y1,x3-x1)\ local real gamma =Atan2(y1-y2,x1-x2)\ local real delta=Atan2(y3-y2,x3-x2)\ local real PI2=bj_PI+bj_PI\ \ call GroupEnumUnitsInRect( inrect, semi,null)\ loop\ set picked=FirstOfGroup(inrect)\ exitwhen picked==null\ set x=GetUnitX(picked)\ set y=GetUnitY(picked)\ if IsUnitInGroup(picked,whichGroup) then\ elseif (GroupAddUnitsInTriangle_AngleCheck(Atan2(y-y1,x-x1),alpha,beta,PI2) and GroupAddUnitsInTriangle_AngleCheck( Atan2(y-y2,x-x2) ,gamma,delta,PI2)) then\ call GroupAddUnit( whichGroup, picked)\ endif\ call GroupRemoveUnit(inrect,picked)\ endloop\ call RemoveRect(semi)\ call DestroyGroup(inrect)\ set whichGroup=null\ set picked=null\ set semi=null\ set inrect=null\ endfunction\ \ //*******************************************************************\ //* End External *\ //*******************************************************************\ \ function Flare_EffectRemove takes nothing returns nothing\ call KillUnit(GetEnumUnit())\ endfunction\ \ function Flare_ForceUIKey takes nothing returns nothing\ local timer T = GetExpiredTimer()\ local integer PId = GetAttachedInt(T, "Flare_PlayerId")\ local unit U = GetAttachedUnit(T, "Flare_Caster")\ \ call AttachBoolean(U, "Flare_NoDetect", true)\ call IssueImmediateOrder(U, Flare_CancelDetectorOrderId())\ \ if GetLocalPlayer() == Player(PId) then\ call ForceUIKey(Flare_NextPointHotkey())\ endif\ \ call CleanAttachedVars(T)\ call DestroyTimer(T)\ endfunction\ \ function Flare_CancelCast takes nothing returns nothing\ local unit U = GetTriggerUnit()\ local string Reference = "Flare_PlayerData"+I2S(GetPlayerId(GetOwningPlayer(U)))+"_"\ local integer I = 0\ local integer Total = GetAttachedInt(gg_trg_Flare, "Flare_PlayerData_TotalActive")-1\ local integer FlareId = Flare_AbilityId()\ local integer Level = GetUnitAbilityLevel(U, FlareId)\ \ loop\ set I = I+1\ exitwhen I > 3\ call DestroyEffect(GetAttachedEffect(gg_trg_Flare, Reference+"Effect"+I2S(I)))\ endloop\ \ call AttachBoolean(gg_trg_Flare, Reference+"On", false)\ call UnitRemoveAbility(U, Flare_NextPointAbilityId())\ call UnitRemoveAbility(U, Flare_CancelDetectorAbilityId())\ \ call SetUnitState(U, UNIT_STATE_MANA, GetUnitState(U, UNIT_STATE_MANA)+Flare_ManaCost(Level))\ call UnitRemoveAbility(U, FlareId)\ call UnitAddAbility(U, FlareId)\ call UnitMakeAbilityPermanent(U, true, FlareId)\ call SetUnitAbilityLevel(U, FlareId, Level)\ \ call AttachInt(gg_trg_Flare, "Flare_PlayerData_TotalActive", Total)\ if Total == 0 then\ call PauseTimer(GetAttachedTimer(gg_trg_Flare, "Flare_CheckTimer"))\ endif\ \ set U = null\ endfunction\ \ function Flare_PeriodicCancelCheck takes nothing returns nothing\ local integer I = -1\ local player LocalPlayer = GetLocalPlayer()\ local string HK = Flare_CancelDetectorHotkey()\ \ loop\ set I = I+1\ exitwhen I > 15\ if GetAttachedBoolean(gg_trg_Flare, "Flare_PlayerData"+I2S(I)+"_On") then\ if LocalPlayer == Player(I) then\ call ForceUIKey(HK)\ endif\ endif\ endloop\ endfunction\ \ function Flare_DamageCallback takes nothing returns nothing\ local integer I = 0\ local integer TotalSlots = GetAttachedInt(gg_trg_Flare, "Flare_DamageData_TotalActive")\ local integer ArrayIndex\ local unit U\ local unit U2\ local group G = CreateGroup()\ local group Affected = CreateGroup()\ local group Effects\ local real X1\ local real Y1\ local real X2\ local real Y2\ local real X3\ local real Y3\ local integer Level\ local integer Countdown\ local real Damage\ local unit Dummy = CreateUnit(Player(15), Flare_DummyUnitId(), 0.00, 0.00, 0.00)\ local string BuffOrderString = Flare_BuffAbilityOrderId()\ \ call UnitAddAbility(Dummy, Flare_BuffAbilityId())\ call UnitRemoveAbility(Dummy, 'Amov')\ set bj_meleeTwinkedHeroes[30] = Flare_BuffId()\ \ set I = 0\ loop\ set I = I+1\ exitwhen I > TotalSlots\ \ set ArrayIndex = GetAttachedInt(gg_trg_Flare, "Flare_DamageData_Arrays"+I2S(I))\ set Countdown = GetArrayInt(ArrayIndex, 3)-1\ \ if Countdown >= 0 then\ call SetArrayInt(ArrayIndex, 3, Countdown)\ set Damage = GetArrayReal(ArrayIndex, 4)\ set U = GetArrayUnit(ArrayIndex, 1)\ set Level = GetArrayInt(ArrayIndex, 2)\ \ set X1 = GetArrayReal(ArrayIndex, 6) //Fixing bugs again\ set Y1 = GetArrayReal(ArrayIndex, 7)\ set X2 = GetArrayReal(ArrayIndex, 8)\ set Y2 = GetArrayReal(ArrayIndex, 9)\ set X3 = GetArrayReal(ArrayIndex, 10)\ set Y3 = GetArrayReal(ArrayIndex, 11)\ \ set bj_ghoul[28] = U\ set bj_groupEnumOwningPlayer = GetOwningPlayer(U)\ set bj_forceRandomConsidered = Level\ call GroupAddUnitsInTriangle(G, X1, Y1, X2, Y2, X3, Y3) //, Condition(function Flare_Filter))\ \ loop\ set U2 = FirstOfGroup(G)\ exitwhen U2 == null\ \ if Flare_DamageFilter(U, U2, bj_groupEnumOwningPlayer, Level) then\ call UnitDamageTarget(U, U2, Damage, true, false, ATTACK_TYPE_CHAOS, DAMAGE_TYPE_UNIVERSAL, null)\ call GroupAddUnit(Affected, U2)\ \ if GetUnitAbilityLevel(U2, bj_meleeTwinkedHeroes[30]) == 0 then\ call SetUnitX(Dummy, GetUnitX(U2))\ call SetUnitY(Dummy, GetUnitY(U2))\ call IssueTargetOrder(U, BuffOrderString, U2)\ endif\ \ endif\ call GroupRemoveUnit(G, U2)\ endloop\ else\ set Effects = GetArrayGroup(ArrayIndex, 5)\ call ForGroup(Effects, function Flare_EffectRemove)\ call DestroyGroup(Effects)\ set Effects = null\ \ call DestroyArray(ArrayIndex)\ \ if TotalSlots > 1 then\ call AttachInt(gg_trg_Flare, "Flare_DamageData_Arrays"+I2S(I), GetAttachedInt(gg_trg_Flare, "Flare_DamageData_Arrays"+I2S(TotalSlots)))\ set I = I-1\ else\ call PauseTimer(GetExpiredTimer())\ endif\ \ call AttachInt(gg_trg_Flare, "Flare_DamageData_Arrays"+I2S(TotalSlots), 0)\ set TotalSlots = TotalSlots-1\ endif\ endloop\ \ set bj_groupAddGroupDest = Affected\ call GroupEnumUnitsInRect(G, bj_mapInitialPlayableArea, Condition(function Flare_BuffFilter))\ \ call AttachInt(gg_trg_Flare, "Flare_DamageData_TotalActive", TotalSlots)\ \ call DestroyGroup(G)\ call DestroyGroup(Affected)\ call UnitApplyTimedLife(Dummy, 'BTLF', 1.00)\ set G = null\ set Affected = null\ set Dummy = null\ endfunction\ \ function Flare_CreateEffectsPeriodic takes nothing returns nothing\ local integer ArrayIndex\ local integer I = 0\ local integer TotalSlots = GetAttachedInt(gg_trg_Flare, "Flare_EffectData_TotalActive")\ local real X\ local real Y\ local real DX\ local real DY\ local integer EffectUnitId = Flare_EffectUnitId()\ local unit EffectUnit\ local integer Segment\ local integer Count\ local integer DamageTotalSlots\ local integer DamageArray\ local integer Level\ local real Damage\ \ loop\ set I = I+1\ exitwhen I > TotalSlots\ \ set ArrayIndex = GetAttachedInt(gg_trg_Flare, "Flare_EffectData_Arrays"+I2S(I))\ set Count = GetArrayInt(ArrayIndex, 3)-1\ \ if Count >= 0 then\ call SetArrayInt(ArrayIndex, 3, Count)\ \ set X = GetArrayReal(ArrayIndex, 13) //If they're not set to variables first\ set DX = GetArrayReal(ArrayIndex, 10) //This will bug out.\ set X = X+DX\ set Y = GetArrayReal(ArrayIndex, 14)\ set DY = GetArrayReal(ArrayIndex, 11)\ set Y = Y+DY\ \ call SetArrayReal(ArrayIndex, 13, X)\ call SetArrayReal(ArrayIndex, 14, Y)\ \ set EffectUnit = CreateUnit(Player(15), EffectUnitId, X, Y, GetRandomReal(0.00, 360.00))\ call SetUnitTimeScale(EffectUnit, Flare_EffectUnitAnimationSpeed(GetArrayInt(ArrayIndex, 2)))\ call GroupAddUnit(GetArrayGroup(ArrayIndex, 12), EffectUnit)\ else\ set Segment = GetArrayInt(ArrayIndex, 15)+1\ \ if Segment <= 3 then\ call SetArrayInt(ArrayIndex, 15, Segment)\ set Count = GetArrayInt(ArrayIndex, 16)\ call SetArrayInt(ArrayIndex, 3, Count)\ \ if Segment == 2 then\ set X = GetArrayReal(ArrayIndex, 6)\ set Y = GetArrayReal(ArrayIndex, 7)\ call SetArrayReal(ArrayIndex, 10, (GetArrayReal(ArrayIndex, 4)-X)/Count)\ call SetArrayReal(ArrayIndex, 11, (GetArrayReal(ArrayIndex, 5)-Y)/Count)\ else\ set X = GetArrayReal(ArrayIndex, 4)\ set Y = GetArrayReal(ArrayIndex, 5)\ call SetArrayReal(ArrayIndex, 10, (GetArrayReal(ArrayIndex, 8)-X)/Count)\ call SetArrayReal(ArrayIndex, 11, (GetArrayReal(ArrayIndex, 9)-Y)/Count)\ endif\ \ call SetArrayReal(ArrayIndex, 13, X)\ call SetArrayReal(ArrayIndex, 14, Y)\ else\ set Level = GetArrayInt(ArrayIndex, 2)\ set Damage = GetArrayReal(ArrayIndex, 17) //Again, avoiding bugs\ set DamageArray = NewArray(12, true)\ \ call SetArrayObject(DamageArray, 1, GetArrayUnit(ArrayIndex, 1))\ call SetArrayInt(DamageArray, 2, Level)\ call SetArrayInt(DamageArray, 3, R2I(Flare_Duration(Level)/Flare_DamageTimerInterval()))\ call SetArrayReal(DamageArray, 4, Damage)\ call SetArrayObject(DamageArray, 5, GetArrayGroup(ArrayIndex, 12))\ \ set X = GetArrayReal(ArrayIndex, 4)\ set Y = GetArrayReal(ArrayIndex, 5)\ call SetArrayReal(DamageArray, 6, X)\ call SetArrayReal(DamageArray, 7, Y)\ \ set X = GetArrayReal(ArrayIndex, 6)\ set Y = GetArrayReal(ArrayIndex, 7)\ call SetArrayReal(DamageArray, 8, X)\ call SetArrayReal(DamageArray, 9, Y)\ \ set X = GetArrayReal(ArrayIndex, 8)\ set Y = GetArrayReal(ArrayIndex, 9)\ call SetArrayReal(DamageArray, 10, X)\ call SetArrayReal(DamageArray, 11, Y)\ \ set DamageTotalSlots = GetAttachedInt(gg_trg_Flare, "Flare_DamageData_TotalActive")+1\ call AttachInt(gg_trg_Flare, "Flare_DamageData_TotalActive", DamageTotalSlots)\ call AttachInt(gg_trg_Flare, "Flare_DamageData_Arrays"+I2S(DamageTotalSlots), DamageArray)\ \ if DamageTotalSlots == 1 then\ call TimerStart(GetAttachedTimer(gg_trg_Flare, "Flare_DamageTimer"), Flare_DamageTimerInterval(), true, function Flare_DamageCallback)\ endif\ \ call DestroyArray(ArrayIndex)\ \ if TotalSlots > 1 then\ call AttachInt(gg_trg_Flare, "Flare_EffectData_Arrays"+I2S(I), GetAttachedInt(gg_trg_Flare, "Flare_Arrays"+I2S(TotalSlots)))\ set I = I-1\ else\ call PauseTimer(GetExpiredTimer())\ endif\ \ call AttachInt(gg_trg_Flare, "Flare_EffectData_Arrays"+I2S(TotalSlots), 0)\ set TotalSlots = TotalSlots-1\ endif\ endif\ endloop\ \ call AttachInt(gg_trg_Flare, "Flare_EffectData_TotalActive", TotalSlots)\ set EffectUnit = null\ endfunction\ \ function Flare_CastFinished takes player P, integer Level, unit U, string Reference returns nothing\ local integer Total = GetAttachedInt(gg_trg_Flare, "Flare_PlayerData_TotalActive")-1\ local real X1 = GetAttachedReal(gg_trg_Flare, Reference+"X1")\ local real Y1 = GetAttachedReal(gg_trg_Flare, Reference+"Y1")\ local real X2 = GetAttachedReal(gg_trg_Flare, Reference+"X2")\ local real Y2 = GetAttachedReal(gg_trg_Flare, Reference+"Y2")\ local real X3 = GetAttachedReal(gg_trg_Flare, Reference+"X3")\ local real Y3 = GetAttachedReal(gg_trg_Flare, Reference+"Y3")\ local real A = SquareRoot((X2-X1)*(X2-X1)+(Y2-Y1)*(Y2-Y1)) //Ouch... but Heron's Formula was the\ local real B = SquareRoot((X3-X2)*(X3-X2)+(Y3-Y2)*(Y3-Y2)) //Easiest way...\ local real C = SquareRoot((X1-X3)*(X1-X3)+(Y1-Y3)*(Y1-Y3))\ local real S = (A+B+C)/2\ local integer ArrayIndex = NewArray(18, true)\ local integer Count = Flare_NumberOfEffectsPerSegment(Level, B)\ local group G = CreateGroup()\ local unit EffectUnit = CreateUnit(Player(15), Flare_EffectUnitId(), X3, Y3, GetRandomReal(0.00, 360.00))\ \ call SetArrayObject(ArrayIndex, 1, U)\ call SetArrayInt(ArrayIndex, 2, Level)\ call SetArrayInt(ArrayIndex, 3, Count)\ call SetArrayReal(ArrayIndex, 4, X1)\ call SetArrayReal(ArrayIndex, 5, Y1)\ call SetArrayReal(ArrayIndex, 6, X2)\ call SetArrayReal(ArrayIndex, 7, Y2)\ call SetArrayReal(ArrayIndex, 8, X3)\ call SetArrayReal(ArrayIndex, 9, Y3)\ call SetArrayReal(ArrayIndex, 10, (X2-X3)/Count)\ call SetArrayReal(ArrayIndex, 11, (Y2-Y3)/Count)\ call SetArrayObject(ArrayIndex, 12, G)\ call SetArrayReal(ArrayIndex, 13, X3)\ call SetArrayReal(ArrayIndex, 14, Y3)\ call SetArrayInt(ArrayIndex, 15, 1)\ call SetArrayInt(ArrayIndex, 16, Count)\ call SetArrayReal(ArrayIndex, 17, Flare_DamagePerSecond(Level, SquareRoot(S*(S-A)*(S-B)*(S-C)))*Flare_DamageTimerInterval())\ \ call SetUnitTimeScale(EffectUnit, Flare_EffectUnitAnimationSpeed(Level))\ call GroupAddUnit(G, EffectUnit)\ \ call AttachBoolean(gg_trg_Flare, Reference+"On", false)\ call UnitRemoveAbility(U, Flare_NextPointAbilityId())\ call UnitRemoveAbility(U, Flare_CancelDetectorAbilityId())\ \ call AttachInt(gg_trg_Flare, "Flare_PlayerData_TotalActive", Total)\ if Total == 0 then\ call PauseTimer(GetAttachedTimer(gg_trg_Flare, "Flare_CheckTimer"))\ endif\ \ set Total = GetAttachedInt(gg_trg_Flare, "Flare_EffectData_TotalActive")+1\ call AttachInt(gg_trg_Flare, "Flare_EffectData_TotalActive", Total)\ call AttachInt(gg_trg_Flare, "Flare_EffectData_Arrays"+I2S(Total), ArrayIndex)\ if Total == 1 then\ call TimerStart(GetAttachedTimer(gg_trg_Flare, "Flare_EffectTimer"), Flare_EffectCreationInterval(), true, function Flare_CreateEffectsPeriodic)\ endif\ \ set G = null\ endfunction\ \ function Flare_NextPointCast takes nothing returns nothing\ local unit U = GetTriggerUnit()\ local player P = GetOwningPlayer(U)\ local string Reference = "Flare_PlayerData"+I2S(GetPlayerId(P))+"_"\ local integer PointNum = GetAttachedInt(gg_trg_Flare, Reference+"PointsDone")+1\ local string EffectPath = ""\ local integer Level = GetAttachedInt(gg_trg_Flare, Reference+"Level")\ local integer I\ local real X = GetOrderPointX()\ local real Y = GetOrderPointY()\ \ if GetLocalPlayer() == P then\ set EffectPath = Flare_PointIndicatorEffect()\ endif\ \ call AttachInt(gg_trg_Flare, Reference+"PointsDone", PointNum)\ call AttachReal(gg_trg_Flare, Reference+"X"+I2S(PointNum), X)\ call AttachReal(gg_trg_Flare, Reference+"Y"+I2S(PointNum), Y)\ call AttachObject(gg_trg_Flare, Reference+"Effect"+I2S(PointNum), AddSpecialEffect(EffectPath, X, Y))\ \ if PointNum >= 3 then\ set I = 0\ loop\ set I = I+1\ exitwhen I > PointNum\ call DestroyEffect(GetAttachedEffect(gg_trg_Flare, Reference+"Effect"+I2S(I)))\ endloop\ \ call UnitRemoveAbility(U, Flare_NextPointAbilityId())\ call Flare_CastFinished(P, Level, U, Reference)\ else\ call AttachBoolean(U, "Flare_NoDetect", true)\ call IssueImmediateOrder(U, Flare_CancelDetectorOrderId())\ \ if GetLocalPlayer() == P then\ call ForceUIKey(Flare_NextPointHotkey())\ endif\ endif\ \ set U = null\ endfunction\ \ function Flare_MainCast takes nothing returns nothing\ local unit U = GetTriggerUnit()\ local location L = GetSpellTargetLoc()\ local player P = GetOwningPlayer(U)\ local string Reference = "Flare_PlayerData"+I2S(GetPlayerId(P))+"_"\ local string EffectPath = ""\ local real X = GetLocationX(L)\ local real Y = GetLocationY(L)\ local integer Total = GetAttachedInt(gg_trg_Flare, "Flare_PlayerData_TotalActive")+1\ local timer T = CreateTimer()\ \ call GroupAddUnit(GetAttachedGroup(gg_trg_Flare, "Flare_PlayerData_CastingUnits"), U)\ call UnitAddAbility(U, Flare_NextPointAbilityId())\ call UnitAddAbility(U, Flare_CancelDetectorAbilityId())\ \ if GetLocalPlayer() == P then\ set EffectPath = Flare_PointIndicatorEffect()\ endif\ \ call AttachInt(T, "Flare_PlayerId", GetPlayerId(P))\ call AttachObject(T, "Flare_Caster", U)\ call TimerStart(T, Flare_CastHotkeyPressDelay(), false, function Flare_ForceUIKey)\ \ call AttachBoolean(gg_trg_Flare, Reference+"On", true)\ call AttachInt(gg_trg_Flare, Reference+"Level", GetUnitAbilityLevel(U, Flare_AbilityId()))\ call AttachInt(gg_trg_Flare, Reference+"PointsDone", 1)\ call AttachObject(gg_trg_Flare, Reference+"Effect1", AddSpecialEffect(EffectPath, X, Y))\ call AttachReal(gg_trg_Flare, Reference+"X1", X)\ call AttachReal(gg_trg_Flare, Reference+"Y1", Y)\ \ call AttachInt(gg_trg_Flare, "Flare_PlayerData_TotalActive", Total)\ if Total == 1 then\ call TimerStart(GetAttachedTimer(gg_trg_Flare, "Flare_CheckTimer"), Flare_CheckInterval(), true, function Flare_PeriodicCancelCheck)\ endif\ \ call RemoveLocation(L)\ set L = null\ set U = null\ endfunction\ \ function Flare_Init takes nothing returns nothing\ local unit U = CreateUnit(Player(15), Flare_DummyUnitId(), 0.00, 0.00, 0.00)\ \ call AttachObject(gg_trg_Flare, "Flare_DamageTimer", GetExpiredTimer())\ call AttachObject(gg_trg_Flare, "Flare_CheckTimer", CreateTimer())\ call AttachObject(gg_trg_Flare, "Flare_EffectTimer", CreateTimer())\ call AttachObject(gg_trg_Flare, "Flare_PlayerData_CastingUnits", CreateGroup())\ \ call Preload(Flare_PointIndicatorEffect())\ call UnitAddAbility(U, Flare_AbilityId())\ call UnitAddAbility(U, Flare_BuffAbilityId())\ call UnitAddAbility(U, Flare_NextPointAbilityId())\ call UnitAddAbility(U, Flare_CancelDetectorAbilityId())\ \ call RemoveUnit(U)\ set U = null\ endfunction\ \ //===========================================================================\ function InitTrig_Flare takes nothing returns nothing\ local trigger T = CreateTrigger()\ set gg_trg_Flare = CreateTrigger()\ \ call TriggerRegisterAnyUnitEventBJ(gg_trg_Flare, EVENT_PLAYER_UNIT_SPELL_EFFECT)\ call TriggerAddCondition(gg_trg_Flare, Condition(function Flare_MainCastConditions))\ call TriggerAddAction(gg_trg_Flare, function Flare_MainCast)\ \ call TriggerRegisterAnyUnitEventBJ(T, EVENT_PLAYER_UNIT_ISSUED_POINT_ORDER)\ call TriggerAddCondition(T, Condition(function Flare_NextPointCastConditions))\ call TriggerAddAction(T, function Flare_NextPointCast)\ \ set T = CreateTrigger()\ call TriggerRegisterAnyUnitEventBJ(T, EVENT_PLAYER_UNIT_SPELL_CAST)\ call TriggerAddCondition(T, Condition(function Flare_CancelCastConditions))\ call TriggerAddAction(T, function Flare_CancelCast)\ \ call TimerStart(CreateTimer(), 0.10, false, function Flare_Init) //Because CSCache isn't initialized yet.\ \ set T = null\ endfunction\ \ \ \ \ }