cleeezzz
The Undead Ranger.
- Reaction score
- 268
k added that, everything bugged now, the GS scope now fails to do anything.
I really don't like the word multi instanceable. It's just so confusing.because structs can be multi instanceable but libraries cant
local Data d = 1
set d.moved = 1.1
local integer d = 1
set somePrefixName_moved[d] = 1.1
set CAS_e = 5
set CAS_e.moved = 5.5
set CAS_e = 5
set somePrefixName_moved[CAS_e] = 5.5
i kinda see what you mean, but how does that help me get e.moved from a specific struct instance? like, i can run CAS 5 times, and have 5 structs. how do i get e.moved from the one i want.
call SetUnitFacing(u, GetUnitFacing(u) - (CAS_e.moved/11))
When you pick units in range, your link must be the units themselves. Use PUI. You don't need the global variable CAS_e.GS, picks all arrows in range
library CAS requires CSData,CSSafety,HandyFunctions
globals
private constant real Start = 50.00
private constant real Scale = 1.00
private constant real Fly_height = 60.00
private constant attacktype A = ATTACK_TYPE_CHAOS
private constant damagetype D = DAMAGE_TYPE_UNIVERSAL
private unit Caster = null
endglobals
private function FilterIsEnemyAlive takes nothing returns boolean
return IsUnitEnemy(GetFilterUnit(), GetOwningPlayer(Caster)) and GetWidgetLife(GetFilterUnit())>0.405
endfunction
//=======================================================================
private struct Arrow
//! runtextmacro PUI()
unit u
unit d
unit a
real moved
real cd
real maxd
real dmg
real angle
real r
real plx
real ply
real bases
group g = CreateGroup()
timer t
integer aid
integer lvl
real int
real next
boolean spell
string sfx
string as
integer func
integer slow
real csd
static method create takes integer ut, unit u, real cx, real cy, real tx, real ty, real period, real r, real moved, real maxd, real dmg, integer aid, string as, integer lvl, real int, string sfx, integer func returns Arrow
local integer index
local item indexItem
local integer i
local Arrow d = Arrow<u>
set d.t = NewTimer()
set d.u = u
set d.cd = Start
set d.csd = 0
set d.maxd = maxd
set d.angle = AngleXY(cx,cy,tx,ty)
set d.dmg = dmg
set d.r = r
set d.d = CreateUnit(GetOwningPlayer(u),ut, PolarProjectionX (cx, Start, d.angle), PolarProjectionY (cy, Start, d.angle) , Rad2Deg(d.angle))
set d.plx = GetUnitX(d.d)
set d.ply = GetUnitY(d.d)
set d.slow = 0
call GroupAddUnit(Arrows,d.d)
call SetUnitMoveSpeed(d.d, moved)
set d.bases = moved
set index = 0
loop
exitwhen index > 5
set indexItem = UnitItemInSlot(u, index)
if indexItem != null then
if GetItemTypeId(indexItem) == 039;I00G039; or GetItemTypeId(indexItem) == 039;I00M039; then
set i = GetRandomInt(1, 100)
if i <= 15 then
call UnitAddItemById(d.d,039;I00V039;)
endif
endif
if GetItemTypeId(indexItem) == 039;I00J039; or GetItemTypeId(indexItem) == 039;I00M039; then
set i = GetRandomInt(1 , 100)
if i <= 15 then
call UnitAddItemById(d.d,039;I00X039;)
endif
endif
if GetItemTypeId(indexItem) == 039;I00F039; or GetItemTypeId(indexItem) == 039;I00M039; then
set i = GetRandomInt(1 , 100)
if i <= 17 then
call UnitAddItemById(d.d, 039;I00W039;)
endif
endif
if GetItemTypeId(indexItem) == 039;I007039; then
set i = GetRandomInt(1 , 100)
if i <= 10 then
call UnitAddItemById(d.d, 039;I007039;)
endif
endif
if GetItemTypeId(indexItem) == 039;I006039; then
set i = GetRandomInt(1 , 100)
if i <= 15 then
call UnitAddItemById(d.d, 039;I006039;)
endif
endif
if GetItemTypeId(indexItem) == 039;I008039; then
set i = GetRandomInt(1 , 100)
if i <= 20 then
call UnitAddItemById(d.d, 039;I008039;)
endif
endif
endif
set index = index + 1
endloop
set indexItem = null
set d.moved = moved
set Caster = u
if aid != 0 and sfx != null then
set d.spell = true
if aid != 0 then
set d.aid = aid
set d.as = as
set d.int = int
set d.next = int
set d.a = CreateUnit(GetOwningPlayer(u),039;h000039;,cx,cy,0)
call UnitAddAbility(d.a,aid)
call SetUnitAbilityLevel(d.a,aid,lvl)
call UnitApplyTimedLife(d.a,039;BTLF039;,60)
else
set d.aid = 0
endif
if sfx != null then
set d.sfx = sfx
else
set d.sfx = null
endif
else
set d.spell = false
endif
if func == 1 then
if GetUnitState( u, UNIT_STATE_MANA) >= 1 then
call SetUnitState( u, UNIT_STATE_MANA, GetUnitState( u, UNIT_STATE_MANA) - 1)
call SetUnitMoveSpeed(d.d, moved - 7)
set d.bases = moved - 7
set d.func = func
else
set d.func = 0
endif
else
set d.func = 0
endif
call SetUnitPathing(d.d,false)
call SetUnitScale(d.d,Scale,Scale,Scale)
call SetUnitFlyHeight(d.d,Fly_height,0.00)
call TimerStart(d.t,period,true,function Arrow.Execute)
call SetCSData(d.t,d)
return d
endmethod
static method Execute takes nothing returns nothing
local real x
local real y
local real x2
local real y2
local real a
local unit u
local group g = CreateGroup()
local real dist
local real rdist
local Arrow d = GetCSData(GetExpiredTimer())
set x = GetUnitX(d.d)
set y = GetUnitY(d.d)
set rdist = DistanceXY( x, y, d.plx, d.ply)
if d.slow == 0 then
set d.moved = GetUnitMoveSpeed(d.d)
if GetUnitMoveSpeed(d.d) < d.bases then
call SetUnitMoveSpeed(d.d, GetUnitMoveSpeed(d.d) + 0.3)
endif
endif
set d.cd = d.cd + rdist
set d.plx = x
set d.ply = y
if d.cd >= d.maxd or d.d == null then
call d.destroy()
set u = null
call DestroyGroup(g)
set g = null
return
endif
set d.angle = Deg2Rad(GetUnitFacing(d.d))
set x = PolarProjectionX(x, d.moved, d.angle)
set y = PolarProjectionY(y, d.moved, d.angle)
if x > GMaxX or x < GMinX or y > GMaxY or y < GMinY then
call RemoveUnit(d.d)
set u = null
call DestroyGroup(g)
set g = null
call d.destroy()
return
endif
call SetUnitX(d.d, x)
call SetUnitY(d.d, y)
call GroupEnumUnitsInRange(g,x,y,d.r,Condition(function FilterIsEnemyAlive))
loop
set u = FirstOfGroup(g)
exitwhen u == null
if not(IsUnitInGroup(u,d.g)) then
call GroupAddUnit(d.g,u)
call UnitDamageTarget(d.d,u,d.dmg,false,false,A,D,null)
endif
call GroupRemoveUnit(g,u)
endloop
call DestroyGroup(g)
set g = null
if GetUnitState(d.d, UNIT_STATE_LIFE) > .405 then
if d.spell == true then
set d.csd = d.csd + rdist
if d.csd >= d.int then
set d.csd = 0
if d.aid != 0 then
call IssuePointOrder(d.a, d.as, x, y)
endif
if d.sfx != null then
call DestroyEffect(AddSpecialEffect( d.sfx, x, y ))
endif
endif
endif
endif
if d.func == 1 then
set g = CreateGroup()
call GroupEnumUnitsInRange(g,x,y,600,Condition(function FilterIsEnemyAlive))
call GroupAddGroupAdv(Arrows, g)
loop
set u = FirstOfGroup(g)
if u == d.d then
call GroupRemoveUnit(g,u)
set u = FirstOfGroup(g)
endif
exitwhen u == null
set x2 = GetUnitX(u)
set y2 = GetUnitY(u)
set dist = DistanceXY(x,y,x2,y2)
if dist <= 600 then
set a = AngleXY(x2,y2,x,y)
if 400/dist <= dist then
set x2 = SafeX(PolarProjectionX(x2,(400/dist),a))
set y2 = SafeY(PolarProjectionY(y2,(400/dist),a))
endif
call SetUnitX(u,x2)
call SetUnitY(u,y2)
endif
call GroupRemoveUnit(g,u)
endloop
call DestroyGroup(g)
set g = null
endif
endmethod
private method onDestroy takes nothing returns nothing
call RemoveUnit(.d)
call RemoveUnit(.a)
set .u = null
set .d = null
set .a = null
call GroupRemoveUnit(Arrows,.d)
call GroupClear(.g)
call DestroyGroup(.g)
set .g = null
call ReleaseTimer(.t)
set .spell = false
set .func = 0
endmethod
endstruct
public function SA takes integer ut, unit u, real cx, real cy, real tx, real ty, real period, real r, real moved, real maxd, real dmg, integer aid, string as, integer lvl, real int, string sfx, integer func returns nothing
call Arrow.create(ut,u,cx,cy,tx,ty,period,r,moved,maxd,dmg,aid,as,lvl,int,sfx,func)
endfunction
endlibrary
</u>
scope GF initializer Init
private struct Data
timer t
unit d
real x
real y
integer i
group g = CreateGroup()
private method onDestroy takes nothing returns nothing
call ReleaseTimer(.t)
call RemoveUnit(.d)
call DestroyGroup(.g)
set .g = null
set .d = null
endmethod
endstruct
private function Shift takes nothing returns nothing
local Data d = GetCSData(GetExpiredTimer())
local unit u
local real a
local real dist
local real x2
local real y2
local real f
local real f2
local group g = CreateGroup()
local Arrow e //undefined variable "arrow", isn't this how you use PUI, but it cant seem to find the struct Arrow, i even made it public, it cant find it, do i have to make it global?
set d.x = GetUnitX(d.d)
set d.y = GetUnitY(d.d)
call GroupAddGroupAdv(Arrows,g)
if GetUnitState(d.d,UNIT_STATE_LIFE)<.405 then
call d.destroy()
set u = null
call DestroyGroup(g)
set g = null
return
endif
loop
set u = FirstOfGroup(g)
exitwhen u == null
set e = Arrow<u>
set x2 = GetUnitX(u)
set y2 = GetUnitY(u)
set f = GetUnitFacing(u)
set f2 = f + 180
set dist = DistanceXY(d.x,d.y,x2,y2)
if dist <= d.i then
set a = Rad2Deg(AngleXY(x2,y2,d.x,d.y))
if a < 0 then
set a = a + 360
endif
if f > 180 then
if a <= f and a >= f2 - 360 then
call SetUnitFacing(u, GetUnitFacing(u) - 3)
else
call SetUnitFacing(u, GetUnitFacing(u) + 3)
endif
else
if a >= f and a <= f2 then
call SetUnitFacing(u, GetUnitFacing(u) + 3)
else
call SetUnitFacing(u, GetUnitFacing(u) - 3)
endif
endif
endif
call GroupRemoveUnit(g,u)
endloop
call DestroyGroup(g)
set g = null
set u = null
endfunction
//=======================================================================
private function Actions takes nothing returns nothing
local Data d = Data.create()
local unit u = GetTriggerUnit()
local location l = GetSpellTargetLoc()
call RemoveUnit(GF[GetPlayerId(GetOwningPlayer(u))])
set GF[GetPlayerId(GetOwningPlayer(u))] = null
set d.t = NewTimer()
set d.x = GetLocationX(l)
set d.y = GetLocationY(l)
set d.d = CreateUnit(GetOwningPlayer(u), 039;h00L039;, d.x, d.y, 0)
set GF[GetPlayerId(GetOwningPlayer(u))] = d.d
set d.i = (200 + (100 * GetUnitAbilityLevel( u, 039;A01W039;)))
call TimerStart(d.t, 0.03, true, function Shift)
call SetCSData(d.t, d)
call RemoveLocation(l)
set u = null
set l = null
endfunction
//=======================================================================
private function Conditions takes nothing returns boolean
return GetSpellAbilityId() == 039;A01W039;
endfunction
//=======================================================================
private function Init takes nothing returns nothing
local trigger trig = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ(trig,EVENT_PLAYER_UNIT_SPELL_EFFECT)
call TriggerAddCondition(trig,Condition(function Conditions))
call TriggerAddAction(trig,function Actions)
endfunction
endscope
</u>
private struct Arrow
struct Arrow
library CAS requires CSData,CSSafety,HandyFunctions
globals
private constant real Start = 50.00
private constant real Scale = 1.00
private constant real Fly_height = 60.00
private constant attacktype A = ATTACK_TYPE_CHAOS
private constant damagetype D = DAMAGE_TYPE_UNIVERSAL
private unit Caster = null
endglobals
private function FilterIsEnemyAlive takes nothing returns boolean
return IsUnitEnemy(GetFilterUnit(), GetOwningPlayer(Caster)) and GetWidgetLife(GetFilterUnit())>0.405
endfunction
//=======================================================================
struct Arrow
//! runtextmacro PUI()
unit u
unit d
unit a
real moved
real cd
real maxd
real dmg
real angle
real r
real plx
real ply
real bases
group g = CreateGroup()
timer t
integer aid
integer lvl
real int
real next
boolean spell
string sfx
string as
integer func
real csd
static method create takes integer ut, unit u, real cx, real cy, real tx, real ty, real period, real r, real moved, real maxd, real dmg, integer aid, string as, integer lvl, real int, string sfx, integer func returns Arrow
local integer index
local item indexItem
local integer i
local Arrow d = Arrow<u>
set d.t = NewTimer()
set d.u = u
set d.cd = Start
set d.csd = 0
set d.maxd = maxd
set d.angle = AngleXY(cx,cy,tx,ty)
set d.dmg = dmg
set d.r = r
set d.d = CreateUnit(GetOwningPlayer(u),ut, PolarProjectionX (cx, Start, d.angle), PolarProjectionY (cy, Start, d.angle) , Rad2Deg(d.angle))
set d.plx = GetUnitX(d.d)
set d.ply = GetUnitY(d.d)
call GroupAddUnit(Arrows,d.d)
call SetUnitMoveSpeed(d.d, moved)
set d.bases = moved
set index = 0
loop
exitwhen index > 5
set indexItem = UnitItemInSlot(u, index)
if indexItem != null then
if GetItemTypeId(indexItem) == 039;I00G039; or GetItemTypeId(indexItem) == 039;I00M039; then
set i = GetRandomInt(1, 100)
if i <= 15 then
call UnitAddItemById(d.d,039;I00V039;)
endif
endif
if GetItemTypeId(indexItem) == 039;I00J039; or GetItemTypeId(indexItem) == 039;I00M039; then
set i = GetRandomInt(1 , 100)
if i <= 15 then
call UnitAddItemById(d.d,039;I00X039;)
endif
endif
if GetItemTypeId(indexItem) == 039;I00F039; or GetItemTypeId(indexItem) == 039;I00M039; then
set i = GetRandomInt(1 , 100)
if i <= 17 then
call UnitAddItemById(d.d, 039;I00W039;)
endif
endif
if GetItemTypeId(indexItem) == 039;I007039; then
set i = GetRandomInt(1 , 100)
if i <= 10 then
call UnitAddItemById(d.d, 039;I007039;)
endif
endif
if GetItemTypeId(indexItem) == 039;I006039; then
set i = GetRandomInt(1 , 100)
if i <= 15 then
call UnitAddItemById(d.d, 039;I006039;)
endif
endif
if GetItemTypeId(indexItem) == 039;I008039; then
set i = GetRandomInt(1 , 100)
if i <= 20 then
call UnitAddItemById(d.d, 039;I008039;)
endif
endif
endif
set index = index + 1
endloop
set indexItem = null
set d.moved = moved
set Caster = u
if aid != 0 and sfx != null then
set d.spell = true
if aid != 0 then
set d.aid = aid
set d.as = as
set d.int = int
set d.next = int
set d.a = CreateUnit(GetOwningPlayer(u),039;h000039;,cx,cy,0)
call UnitAddAbility(d.a,aid)
call SetUnitAbilityLevel(d.a,aid,lvl)
call UnitApplyTimedLife(d.a,039;BTLF039;,60)
else
set d.aid = 0
endif
if sfx != null then
set d.sfx = sfx
else
set d.sfx = null
endif
else
set d.spell = false
endif
if func == 1 then
if GetUnitState( u, UNIT_STATE_MANA) >= 1 then
call SetUnitState( u, UNIT_STATE_MANA, GetUnitState( u, UNIT_STATE_MANA) - 1)
call SetUnitMoveSpeed(d.d, moved - 7)
set d.bases = moved - 7
set d.func = func
else
set d.func = 0
endif
else
set d.func = 0
endif
call SetUnitPathing(d.d,false)
call SetUnitScale(d.d,Scale,Scale,Scale)
call SetUnitFlyHeight(d.d,Fly_height,0.00)
call TimerStart(d.t,period,true,function Arrow.Execute)
call SetCSData(d.t,d)
return d
endmethod
static method Execute takes nothing returns nothing
local real x
local real y
local real x2
local real y2
local real a
local unit u
local group g = CreateGroup()
local real dist
local real rdist
local Arrow d = GetCSData(GetExpiredTimer())
set x = GetUnitX(d.d)
set y = GetUnitY(d.d)
set rdist = DistanceXY( x, y, d.plx, d.ply)
if d.moved < d.bases then
call SetUnitMoveSpeed(d.d, GetUnitMoveSpeed(d.d) + 0.3)
endif
call BJDebugMsg(R2S(d.moved))
set d.cd = d.cd + rdist
set d.plx = x
set d.ply = y
if d.cd >= d.maxd or d.d == null then
call d.destroy()
set u = null
call DestroyGroup(g)
set g = null
return
endif
set d.angle = Deg2Rad(GetUnitFacing(d.d))
set x = PolarProjectionX(x, d.moved, d.angle)
set y = PolarProjectionY(y, d.moved, d.angle)
if x > GMaxX or x < GMinX or y > GMaxY or y < GMinY then
call RemoveUnit(d.d)
set u = null
call DestroyGroup(g)
set g = null
call d.destroy()
return
endif
call SetUnitX(d.d, x)
call SetUnitY(d.d, y)
call GroupEnumUnitsInRange(g,x,y,d.r,Condition(function FilterIsEnemyAlive))
loop
set u = FirstOfGroup(g)
exitwhen u == null
if not(IsUnitInGroup(u,d.g)) then
call GroupAddUnit(d.g,u)
call UnitDamageTarget(d.d,u,d.dmg,false,false,A,D,null)
endif
call GroupRemoveUnit(g,u)
endloop
call DestroyGroup(g)
set g = null
if GetUnitState(d.d, UNIT_STATE_LIFE) > .405 then
if d.spell == true then
set d.csd = d.csd + rdist
if d.csd >= d.int then
set d.csd = 0
if d.aid != 0 then
call IssuePointOrder(d.a, d.as, x, y)
endif
if d.sfx != null then
call DestroyEffect(AddSpecialEffect( d.sfx, x, y ))
endif
endif
endif
endif
if d.func == 1 then
set g = CreateGroup()
call GroupEnumUnitsInRange(g,x,y,600,Condition(function FilterIsEnemyAlive))
call GroupAddGroupAdv(Arrows, g)
loop
set u = FirstOfGroup(g)
if u == d.d then
call GroupRemoveUnit(g,u)
set u = FirstOfGroup(g)
endif
exitwhen u == null
set x2 = GetUnitX(u)
set y2 = GetUnitY(u)
set dist = DistanceXY(x,y,x2,y2)
if dist <= 600 then
set a = AngleXY(x2,y2,x,y)
if 400/dist <= dist then
set x2 = SafeX(PolarProjectionX(x2,(13200/dist*d.moved),a))
set y2 = SafeY(PolarProjectionY(y2,(13200/dist*d.moved),a))
endif
call SetUnitX(u,x2)
call SetUnitY(u,y2)
endif
call GroupRemoveUnit(g,u)
endloop
call DestroyGroup(g)
set g = null
endif
endmethod
private method onDestroy takes nothing returns nothing
call RemoveUnit(.d)
call RemoveUnit(.a)
set .u = null
set .d = null
set .a = null
call GroupRemoveUnit(Arrows,.d)
call GroupClear(.g)
call DestroyGroup(.g)
set .g = null
call ReleaseTimer(.t)
set .spell = false
set .func = 0
endmethod
endstruct
public function SA takes integer ut, unit u, real cx, real cy, real tx, real ty, real period, real r, real moved, real maxd, real dmg, integer aid, string as, integer lvl, real int, string sfx, integer func returns nothing
call Arrow.create(ut,u,cx,cy,tx,ty,period,r,moved,maxd,dmg,aid,as,lvl,int,sfx,func)
endfunction
endlibrary
</u>
Remove the static keyword from the execute method and try again.
library CAS requires CSData,CSSafety,HandyFunctions
globals
private constant real Start = 50.00
private constant real Scale = 1.00
private constant real Fly_height = 60.00
private constant attacktype A = ATTACK_TYPE_CHAOS
private constant damagetype D = DAMAGE_TYPE_UNIVERSAL
private unit Caster = null
endglobals
private function FilterIsEnemyAlive takes nothing returns boolean
return IsUnitEnemy(GetFilterUnit(), GetOwningPlayer(Caster)) and GetWidgetLife(GetFilterUnit())>0.405
endfunction
//=======================================================================
struct Arrow
//! runtextmacro PUI()
unit u
unit d
unit a
real moved
real cd
real maxd
real dmg
real angle
real r
real plx
real ply
real bases
group g = CreateGroup()
timer t
integer aid
integer lvl
real int
real next
boolean spell
string sfx
string as
integer func
real csd
static method create takes integer ut, unit u, real cx, real cy, real tx, real ty, real period, real r, real moved, real maxd, real dmg, integer aid, string as, integer lvl, real int, string sfx, integer func returns Arrow
local integer index
local item indexItem
local integer i
local Arrow d = Arrow.allocate()
set d.t = NewTimer()
set d.u = u
set d.cd = Start
set d.csd = 0
set d.maxd = maxd
set d.angle = AngleXY(cx,cy,tx,ty)
set d.dmg = dmg
set d.r = r
set d.d = CreateUnit(GetOwningPlayer(u),ut, PolarProjectionX (cx, Start, d.angle), PolarProjectionY (cy, Start, d.angle) , Rad2Deg(d.angle))
set d.plx = GetUnitX(d.d)
set d.ply = GetUnitY(d.d)
call GroupAddUnit(Arrows,d.d)
call SetUnitMoveSpeed(d.d, moved)
set d.bases = moved
set index = 0
loop
exitwhen index > 5
set indexItem = UnitItemInSlot(u, index)
if indexItem != null then
if GetItemTypeId(indexItem) == 039;I00G039; or GetItemTypeId(indexItem) == 039;I00M039; then
set i = GetRandomInt(1, 100)
if i <= 15 then
call UnitAddItemById(d.d,039;I00V039;)
endif
endif
if GetItemTypeId(indexItem) == 039;I00J039; or GetItemTypeId(indexItem) == 039;I00M039; then
set i = GetRandomInt(1 , 100)
if i <= 15 then
call UnitAddItemById(d.d,039;I00X039;)
endif
endif
if GetItemTypeId(indexItem) == 039;I00F039; or GetItemTypeId(indexItem) == 039;I00M039; then
set i = GetRandomInt(1 , 100)
if i <= 17 then
call UnitAddItemById(d.d, 039;I00W039;)
endif
endif
if GetItemTypeId(indexItem) == 039;I007039; then
set i = GetRandomInt(1 , 100)
if i <= 10 then
call UnitAddItemById(d.d, 039;I007039;)
endif
endif
if GetItemTypeId(indexItem) == 039;I006039; then
set i = GetRandomInt(1 , 100)
if i <= 15 then
call UnitAddItemById(d.d, 039;I006039;)
endif
endif
if GetItemTypeId(indexItem) == 039;I008039; then
set i = GetRandomInt(1 , 100)
if i <= 20 then
call UnitAddItemById(d.d, 039;I008039;)
endif
endif
endif
set index = index + 1
endloop
set indexItem = null
set d.moved = moved
set Caster = u
if aid != 0 and sfx != null then
set d.spell = true
if aid != 0 then
set d.aid = aid
set d.as = as
set d.int = int
set d.next = int
set d.a = CreateUnit(GetOwningPlayer(u),039;h000039;,cx,cy,0)
call UnitAddAbility(d.a,aid)
call SetUnitAbilityLevel(d.a,aid,lvl)
call UnitApplyTimedLife(d.a,039;BTLF039;,60)
else
set d.aid = 0
endif
if sfx != null then
set d.sfx = sfx
else
set d.sfx = null
endif
else
set d.spell = false
endif
if func == 1 then
if GetUnitState( u, UNIT_STATE_MANA) >= 1 then
call SetUnitState( u, UNIT_STATE_MANA, GetUnitState( u, UNIT_STATE_MANA) - 1)
call SetUnitMoveSpeed(d.d, moved - 7)
set d.bases = moved - 7
set d.func = func
else
set d.func = 0
endif
else
set d.func = 0
endif
call SetUnitPathing(d.d,false)
call SetUnitScale(d.d,Scale,Scale,Scale)
call SetUnitFlyHeight(d.d,Fly_height,0.00)
set Arrow[d.d] = d
call TimerStart(d.t,period,true,function Arrow.Execute)
call SetCSData(d.t,d)
return d
endmethod
static method Execute takes nothing returns nothing
local real x
local real y
local real x2
local real y2
local real a
local unit u
local group g = CreateGroup()
local real dist
local real rdist
local Arrow d = GetCSData(GetExpiredTimer())
set x = GetUnitX(d.d)
set y = GetUnitY(d.d)
set rdist = DistanceXY( x, y, d.plx, d.ply)
if d.moved < d.bases then
call SetUnitMoveSpeed(d.d, GetUnitMoveSpeed(d.d) + 0.3)
endif
set d.cd = d.cd + rdist
set d.plx = x
set d.ply = y
if d.cd >= d.maxd or d.d == null then
call d.destroy()
set u = null
call DestroyGroup(g)
set g = null
return
endif
set d.angle = Deg2Rad(GetUnitFacing(d.d))
set x = PolarProjectionX(x, d.moved, d.angle)
set y = PolarProjectionY(y, d.moved, d.angle)
if x > GMaxX or x < GMinX or y > GMaxY or y < GMinY then
call d.destroy()
call RemoveUnit(d.d)
set d.d = null
set u = null
call DestroyGroup(g)
set g = null
return
endif
call SetUnitX(d.d, x)
call SetUnitY(d.d, y)
call GroupEnumUnitsInRange(g,x,y,d.r,Condition(function FilterIsEnemyAlive))
loop
set u = FirstOfGroup(g)
exitwhen u == null
if not(IsUnitInGroup(u,d.g)) then
call GroupAddUnit(d.g,u)
call UnitDamageTarget(d.d,u,d.dmg,false,false,A,D,null)
endif
call GroupRemoveUnit(g,u)
endloop
call DestroyGroup(g)
set g = null
if GetUnitState(d.d, UNIT_STATE_LIFE) > .405 then
if d.spell == true then
set d.csd = d.csd + rdist
if d.csd >= d.int then
set d.csd = 0
if d.aid != 0 then
call IssuePointOrder(d.a, d.as, x, y)
endif
if d.sfx != null then
call DestroyEffect(AddSpecialEffect( d.sfx, x, y ))
endif
endif
endif
endif
if d.func == 1 then
set g = CreateGroup()
call GroupEnumUnitsInRange(g,x,y,600,Condition(function FilterIsEnemyAlive))
call GroupAddGroupAdv(Arrows, g)
loop
set u = FirstOfGroup(g)
if u == d.d then
call GroupRemoveUnit(g,u)
set u = FirstOfGroup(g)
endif
exitwhen u == null
set x2 = GetUnitX(u)
set y2 = GetUnitY(u)
set dist = DistanceXY(x,y,x2,y2)
if dist <= 600 then
set a = AngleXY(x2,y2,x,y)
if 400/dist <= dist then
set x2 = SafeX(PolarProjectionX(x2,(13200/dist*d.moved),a))
set y2 = SafeY(PolarProjectionY(y2,(13200/dist*d.moved),a))
endif
call SetUnitX(u,x2)
call SetUnitY(u,y2)
endif
call GroupRemoveUnit(g,u)
endloop
call DestroyGroup(g)
set g = null
endif
endmethod
method onDestroy takes nothing returns nothing
call RemoveUnit(.d)
call RemoveUnit(.a)
set .u = null
set .d = null
set .a = null
call GroupRemoveUnit(Arrows,.d)
call GroupClear(.g)
call DestroyGroup(.g)
set .g = null
call ReleaseTimer(.t)
set .spell = false
set .func = 0
endmethod
endstruct
public function SA takes integer ut, unit u, real cx, real cy, real tx, real ty, real period, real r, real moved, real maxd, real dmg, integer aid, string as, integer lvl, real int, string sfx, integer func returns nothing
call Arrow.create(ut,u,cx,cy,tx,ty,period,r,moved,maxd,dmg,aid,as,lvl,int,sfx,func)
endfunction
endlibrary
(...)
if d.cd >= d.maxd or d.d == null then
call d.destroy()
set u = null
call DestroyGroup(g)
set g = null
return
endif
(...)
if x > GMaxX or x < GMinX or y > GMaxY or y < GMinY then
call d.destroy()
call RemoveUnit(d.d)
set d.d = null
set u = null
call DestroyGroup(g)
set g = null
return
endif
call RemoveUnit(d.d)
set d.d = null