How to destroy the timer?

Komaqtion

You can change this now in User CP.
Reaction score
469
Anyone have an idea how to make it more efficient ???

EDIT: And by the way, how would i go about changing this:

>UnitDamageTarget(GetFilterUnit(), GetFilterUnit()
The units damage themselves. Kills won't register as the caster's?

So it's the caster that gets the kill ?
 

Komaqtion

You can change this now in User CP.
Reaction score
469
Can't say i get what you're saying there, kingkingyyk3 XD
Mind explaining, and/or giving me an example ???
 

Rainther

I guess I should write something of value here...
Reaction score
61
To make the caster damage the unit you'll have to transfer the caster as a variable into the condition, which I'm honestly not sure if it works or not. My method to go through this is

JASS:
local group grp = GetUnitsInRangeOfLoc(...)
local integer i = CountUnitsInGroup(grp)
local unit u
loop
exitwhen i < 1
set u = GroupPickRandomUnit(grp)
if Conditions... then
Damage
call GroupAddUnit(grp, u)
endif
call GroupRemoveUnit(grp, u)
set i = i - 1
endloop


I skip the match units part.
May not be efficient, but it works
 

kingkingyyk3

Visitor (Welcome to the Jungle, Baby!)
Reaction score
216
An example worthes 1000 words:)

JASS:
scope Dummy initializer init
globals
    private constant string e = "Abilities\\Spells\\Human\\Flare\\FlareCaster.mdl"
    private constant string e2 = "Abilities\\Spells\\Human\\MarkOfChaos\\MarkOfChaosTarget.mdl"
    private constant string e1 = "Abilities\\Weapons\\DemolisherFireMissile\\DemolisherFireMissile.mdl"
    private constant string e3 = "Abilities\\Spells\\Orc\\WarStomp\\WarStompCaster.mdl"
    private constant integer SPELL_ID = '0000'
    private constant integer unitid = 'h000'
    private constant integer aid = 'Aloc'
    private constant integer bid = 'BTLF'
    private player p
    private group g = CreateGroup()
    private integer TempStructIndex
endglobals

private struct Data
    unit array du [17]
    unit cs
    real array pointx [17]
    real array pointy [17]
    boolean b
    player p
    group g
    
    static method create takes unit u returns Data
        local Data a = Data.allocate()
        set a.cs = u
        set a.b = false
        set a.p = GetOwningPlayer(a.cs)
        set a.g = CreateGroup()
        return a
    endmethod
    
endstruct

private function Spell_Check takes nothing returns boolean
    return GetSpellAbilityId() == SPELL_ID
endfunction

private function GroupEm takes nothing returns boolean
    local Data a = TempStructIndex
    return GetWidgetLife(GetFilterUnit()) > 0.405 and IsUnitEnemy(GetFilterUnit(), a.p) and IsUnitType(GetFilterUnit(), UNIT_TYPE_MAGIC_IMMUNE) == false and IsUnitInGroup(GetFilterUnit(),a.g) == false
endfunction

private function Move_Dummy takes nothing returns boolean
    local Data a = KT_GetData()
    local real xd
    local real yd
    local integer i = 0
    local group g = CreateGroup()
    local unit temp
    set p = GetOwningPlayer(a.cs)
    loop
        exitwhen i==16
        set g = CreateGroup()
        set xd = GetUnitX(a.du<i>)
        set yd = GetUnitY(a.du<i>)
        set a.pointx<i> = xd+10*Cos((i*22.5)*bj_DEGTORAD)
        set a.pointy<i> = yd+10*Sin((i*22.5)*bj_DEGTORAD)
        set TempStructIndex = a
        call GroupEnumUnitsInRange(g, a.pointx<i>, a.pointy<i>, 150, Filter(function GroupEm))
        loop
            set temp = FirstOfGroup(g)
        exitwhen temp == null
            call UnitDamageTarget(a.cs, temp, 50, true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_NORMAL, null)
            call GroupAddUnit(a.g,temp)
            call GroupRemoveUnit(g,temp)
        endloop
        call DestroyGroup(g)
        call SetUnitX(a.du<i>,a.pointx<i>)
        call SetUnitY(a.du<i>,a.pointy<i>)
        set i = i+1
    endloop
    set temp = null
    set g = null
    return a.b
endfunction

private function Effects takes nothing returns nothing
    local Data a = Data.create(GetTriggerUnit())
    local real xu = GetUnitX(a.cs)
    local real yu = GetUnitY(a.cs)
    local integer i = 0
    set p = GetOwningPlayer(a.cs)
    call DestroyEffect(AddSpecialEffect(e,xu,yu))
    loop
        exitwhen i&gt;=16
        set a.pointx<i> = xu+200*Cos((i*22.5)*bj_DEGTORAD)
        set a.pointy<i> = yu+200*Sin((i*22.5)*bj_DEGTORAD)
        call DestroyEffect(AddSpecialEffect(e,a.pointx<i>,a.pointy<i>))
        call DestroyEffect(AddSpecialEffect(e2,a.pointx<i>,a.pointy<i>))
        set p = GetOwningPlayer(a.cs)
        call GroupEnumUnitsInRange(g, a.pointx<i>, a.pointy<i>, 10, Filter(function GroupEm))
        set a.du<i> = CreateUnit(p,unitid,xu,yu,bj_RADTODEG*Atan2(a.pointy<i>-yu,a.pointx<i>-xu))
        call UnitApplyTimedLife(a.du<i>,&#039;BTLF&#039;,2.5)
        call UnitAddAbility(a.du<i>,aid)
        call DestroyEffectDelayed(AddSpecialEffectTarget(e1,a.du<i>,&quot;chest&quot;),2.5)
        set i = i+1
    endloop
    call KT_Add(function Move_Dummy,a,.05)
    set p = null
    call TriggerSleepAction(2.5)
    set i = 0
    loop
        exitwhen i&gt;=16
        set a.pointx<i> = xu+500*Cos((i*22.5)*bj_DEGTORAD)
        set a.pointy<i> = yu+500*Sin((i*22.5)*bj_DEGTORAD)
        call DestroyEffect(AddSpecialEffect(e3,a.pointx<i>,a.pointy<i>))
        set i = i+1
    endloop
    set a.b = true
    call GroupClear(a.g)
    call DestroyGroup(a.g)
    call a.destroy()
endfunction

private function init takes nothing returns nothing
    local trigger t=CreateTrigger()
    call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT)
    call TriggerAddCondition(t,Condition(function Spell_Check))
    call TriggerAddAction(t,function Effects)
    set t = null
endfunction
endscope
</i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i>
 

Komaqtion

You can change this now in User CP.
Reaction score
469
Thank you soo much kingkingyyk3 :D:D And
An example worthes 1000 words:)
So true !!!!

And, just asking, but isn't it a bit unnecessary that this "small" spell uses 3 different systems ??? (KT2, TimerUtils and Timed Handles)
Is there a way i can use the stuff that Timed Handles are used for (Effects that are destroyed after some time, and with a callback maybe :D) with own functions inside the spell ?

This is what i've tried to do, but i don't know how to continue :S

JASS:
scope Dummy initializer init
globals
    private constant string EFFECT_C = &quot;Abilities\\Spells\\Demon\\DarkPortal\\DarkPortalTarget.mdl&quot;
    private constant string EFFECT_1 = &quot;Abilities\\Spells\\Human\\MarkOfChaos\\MarkOfChaosTarget.mdl&quot;
    private constant string EFFECT_2 = &quot;Abilities\\Spells\\Orc\\WarStomp\\WarStompCaster.mdl&quot;
    private constant string DUMMY_EFFECT = &quot;Abilities\\Weapons\\DemolisherFireMissile\\DemolisherFireMissile.mdl&quot;
    private constant integer SPELL_ID = &#039;0000&#039;
    private constant integer DUMMY_ID = &#039;h000&#039;
    private constant integer LOCUST = &#039;Aloc&#039;
    private constant integer BUFF_ID = &#039;BTLF&#039;
    private player p
    private integer TempStructIndex
    private integer LEVEL
endglobals

private struct Data
    unit array du [17]
    unit cs
    real array pointx [17]
    real array pointy [17]
    boolean b
    player p
    group g
    
    static method create takes unit u returns Data
        local Data a = Data.allocate()
        set a.cs = u
        set a.b = false
        set a.p = GetOwningPlayer(a.cs)
        set a.g = CreateGroup()
        return a
    endmethod
    
endstruct

private function Spell_Check takes nothing returns boolean
    return GetSpellAbilityId() == SPELL_ID
endfunction

function At_Destroy takes nothing returns nothing
    call DestroyEffect(AddSpecialEffect(EFFECT_2,a.pointx<i>,a.pointy<i>))

function DestroyEffectDelayed takes effect e, real dur returns nothing
    local timer t = CreateTimer()
    call TimerStart(t,dur,false, function (

private function GroupEm takes nothing returns boolean
    local Data a = TempStructIndex
    return GetWidgetLife(GetFilterUnit()) &gt; 0.405 and IsUnitEnemy(GetFilterUnit(), a.p) and IsUnitType(GetFilterUnit(), UNIT_TYPE_MAGIC_IMMUNE) == false and IsUnitInGroup(GetFilterUnit(),a.g) == false
endfunction

private function Move_Dummy takes nothing returns boolean
    local Data a = KT_GetData()
    local real xd
    local real yd
    local integer i = 0
    local unit temp
    local group g
    set p = GetOwningPlayer(a.cs)
    loop
        exitwhen i==16
        set g = CreateGroup()
        set xd = GetUnitX(a.du<i>)
        set yd = GetUnitY(a.du<i>)
        set a.pointx<i> = xd+10*Cos((i*22.5)*bj_DEGTORAD)
        set a.pointy<i> = yd+10*Sin((i*22.5)*bj_DEGTORAD)
        set TempStructIndex = a
        call GroupEnumUnitsInRange(g, a.pointx<i>, a.pointy<i>, 50, Filter(function GroupEm))
        loop
            set temp = FirstOfGroup(g)
        exitwhen temp == null
            call UnitDamageTarget(a.cs, temp, 50 + LEVEL * 25, true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_NORMAL, null)
            call GroupAddUnit(a.g,temp)
            call GroupRemoveUnit(g,temp)
        endloop
        call DestroyGroup(g)
        call SetUnitX(a.du<i>,a.pointx<i>)
        call SetUnitY(a.du<i>,a.pointy<i>)
        set i = i+1
    endloop
    set temp = null
    set g = null
    return a.b
endfunction

private function Effects takes nothing returns nothing
    local Data a = Data.create(GetTriggerUnit())
    local real xu = GetUnitX(a.cs)
    local real yu = GetUnitY(a.cs)
    local integer i = 0
    local group g
    local unit temp
    set p = GetOwningPlayer(a.cs)
    set LEVEL = GetUnitAbilityLevel(GetTriggerUnit(),SPELL_ID)
    call DestroyEffect(AddSpecialEffect(EFFECT_C,xu,yu))
    loop
        exitwhen i&gt;=16
        set g = CreateGroup()
        set a.pointx<i> = xu+200*Cos((i*22.5)*bj_DEGTORAD)
        set a.pointy<i> = yu+200*Sin((i*22.5)*bj_DEGTORAD)
        call DestroyEffect(AddSpecialEffect(EFFECT_1,a.pointx<i>,a.pointy<i>))
        set p = GetOwningPlayer(a.cs)
        call GroupEnumUnitsInRange(g, a.pointx<i>, a.pointy<i>, 150, Filter(function GroupEm))
        loop
            set temp = FirstOfGroup(g)
            exitwhen temp == null
            call UnitDamageTarget(a.cs, temp, 50 + LEVEL * 50, true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_NORMAL, null)
            call GroupAddUnit(a.g,temp)
            call GroupRemoveUnit(g,temp)
        endloop
        call DestroyGroup(g)
        set a.du<i> = CreateUnit(p,DUMMY_ID,xu,yu,bj_RADTODEG*Atan2(a.pointy<i>-yu,a.pointx<i>-xu))
        call UnitApplyTimedLife(a.du<i>,BUFF_ID,2.5)
        call UnitAddAbility(a.du<i>,LOCUST)
        call DestroyEffectDelayed(AddSpecialEffectTarget(DUMMY_EFFECT,a.du<i>,&quot;chest&quot;),2.5)
        set i = i+1
    endloop
    call KT_Add(function Move_Dummy,a,.05)
    set p = null
    set temp = null
    set g = null
    call TriggerSleepAction(2.5)
    call GroupClear(a.g)
    set i = 0
    loop
        exitwhen i&gt;=16
        set g = CreateGroup()
        set a.pointx<i> = xu+525*Cos((i*22.5)*bj_DEGTORAD)
        set a.pointy<i> = yu+525*Sin((i*22.5)*bj_DEGTORAD)
        call DestroyEffect(AddSpecialEffect(EFFECT_2,a.pointx<i>,a.pointy<i>))
        set p = GetOwningPlayer(a.cs)
        call GroupEnumUnitsInRange(g, a.pointx<i>, a.pointy<i>, 250, Filter(function GroupEm))
        loop
            set temp = FirstOfGroup(g)
            exitwhen temp == null
            call UnitDamageTarget(a.cs, temp, LEVEL * 100, true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_NORMAL, null)
            call GroupAddUnit(a.g,temp)
            call GroupRemoveUnit(g,temp)
        endloop
        call DestroyGroup(g)
        set i = i+1
    endloop
    set a.b = true
    call GroupClear(a.g)
    call DestroyGroup(a.g)
    set p = null
    set temp = null
    call a.destroy()
endfunction

private function init takes nothing returns nothing
    local trigger t=CreateTrigger()
    call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT)
    call TriggerAddCondition(t,Condition(function Spell_Check))
    call TriggerAddAction(t,function Effects)
    set t = null
endfunction
endscope</i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i>


This is the functions i'm trying to use :S:

JASS:
function At_Destroy takes nothing returns nothing
    call DestroyEffect(AddSpecialEffect(EFFECT_2,a.pointx<i>,a.pointy<i>))

function DestroyEffectDelayed takes effect e, real dur returns nothing
    local timer t = CreateTimer()
    call TimerStart(t,dur,false, function (At_Destroy))
endfunction</i></i>


As i said, i'm trying to remove some effects after some time, and creating a efect when they get destroyed :D
 

kingkingyyk3

Visitor (Welcome to the Jungle, Baby!)
Reaction score
216
Timed Handle(KT2 version)

JASS:
library TimedHandles requires KT
    //! textmacro TIMEDHANDLES takes HANDLE,DESTROY
        
        private struct $HANDLE$struct
            $HANDLE$ var
        endstruct
        
        private function DestroyTimed$HANDLE$ takes nothing returns boolean
            local $HANDLE$struct s = KT_GetData()
            call $DESTROY$(s.var)
            return true
        endfunction
        
        function $DESTROY$Delayed takes $HANDLE$ var, real duration returns nothing
            local $HANDLE$struct s = $HANDLE$struct.create()
            set s.var = var
            call KT_Add(function DestroyTimed$HANDLE$, s, duration)
        endfunction

    //! endtextmacro
    
    //! runtextmacro TIMEDHANDLES(&quot;effect&quot;,&quot;DestroyEffect&quot;)
    //! runtextmacro TIMEDHANDLES(&quot;lightning&quot;,&quot;DestroyLightning&quot;)
    //! runtextmacro TIMEDHANDLES(&quot;weathereffect&quot;,&quot;RemoveWeatherEffect&quot;)
    //! runtextmacro TIMEDHANDLES(&quot;item&quot;,&quot;RemoveItem&quot;)
    //! runtextmacro TIMEDHANDLES(&quot;ubersplat&quot;,&quot;DestroyUbersplat&quot;)
    
endlibrary


You can throw away the TimerUtils.
 

Komaqtion

You can change this now in User CP.
Reaction score
469
Thanks !!!!
Though, any thoughts on how i can make it create a special effect either when that effect is destroyed, or when the dummy expiration timer has ended and the dummies DIE ! XD ???

Please... It looks quite wierd when i can't specify the exact location where the special effects should appear and this would make it alot easier :D
 

kingkingyyk3

Visitor (Welcome to the Jungle, Baby!)
Reaction score
216
>>when the dummy expiration timer has ended and the dummies DIE
Use trigger.

>>a special effect either when that effect is destroyed
You may modify the Timed Handle.
 

Komaqtion

You can change this now in User CP.
Reaction score
469
How would i modify Timed Handles to create that special effect then ????
 

kingkingyyk3

Visitor (Welcome to the Jungle, Baby!)
Reaction score
216
It is free to edit....

I edited it. Take a look.
JASS:
////////////////////////////
// Callback thingy added by kingking
///////////////////////////

library TimedHandles requires KT
    //! textmacro TIMEDHANDLES takes HANDLE,DESTROY
        

        private struct $HANDLE$struct
            $HANDLE$ var
            trigger t
            
        endstruct
        
        private function DestroyTimed$HANDLE$ takes nothing returns boolean
            local $HANDLE$struct s = KT_GetData()
            if s.t != null then
                call TriggerExecute(s.t)
                call TriggerClearActions(s.t)
                call DestroyTrigger(s.t)
                set s.t = null
            endif
            call $DESTROY$(s.var)
            return true
        endfunction
        
        function $DESTROY$Delayed takes $HANDLE$ var, real duration, code callback returns nothing
            local $HANDLE$struct s = $HANDLE$struct.create()
            set s.var = var
            if callback!= null then
                set s.t = CreateTrigger()
                call TriggerAddAction(s.t,callback)
            endif
            call KT_Add(function DestroyTimed$HANDLE$, s, duration)
        endfunction

    //! endtextmacro
    
    //! runtextmacro TIMEDHANDLES(&quot;effect&quot;,&quot;DestroyEffect&quot;)
    //! runtextmacro TIMEDHANDLES(&quot;lightning&quot;,&quot;DestroyLightning&quot;)
    //! runtextmacro TIMEDHANDLES(&quot;weathereffect&quot;,&quot;RemoveWeatherEffect&quot;)
    //! runtextmacro TIMEDHANDLES(&quot;item&quot;,&quot;RemoveItem&quot;)
    //! runtextmacro TIMEDHANDLES(&quot;ubersplat&quot;,&quot;DestroyUbersplat&quot;)
    
endlibrary
 

Rainther

I guess I should write something of value here...
Reaction score
61
Wait... are you adding a special effect through an other special effect?
 

Rainther

I guess I should write something of value here...
Reaction score
61
Concerning this... isn't it easier the to make a timer for each dummy and create the effect when the timer expires? start timer when you add experation timer and have same duration.

EDIT: Read that you're not a fish in the sea concerning Timers. I personally use TimerUtils for it.
 

Komaqtion

You can change this now in User CP.
Reaction score
469
First, can i use KT2 ??
Second, still have no clue how to work with timer ! :(

JASS:
scope Dummy initializer init
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//*************************************************************************************************************************//
//@@///////////////////////////////////////////Burning Hell, Made By Komaqtion///////////////////////////////////////////@@//
//@@                                                                                                                     @@//
//@@                                                 How to import:                                                      @@//
//@@                                                                                                                     @@//
//@@               ¤ First copy the ability &quot;Burning Hell&quot; and the unit &quot;Dummy&quot; and change the ID&#039;s in the               @@//
//@@               constants below to the new ones. Then you need to import Vexorian&#039;s dummy.mdx file from               @@//
//@@               this map, or another, and change &quot;Dummy&quot; unit&#039;s model to this one. Then, of course, you               @@//
//@@               need to import the triggers, which are in the categories &quot;The Spell&quot; and                              @@//
//@@               &quot;Required Systems&quot;. Then you&#039;re free to change any of the given global constants to suit              @@//
//@@               your needs.                                                                                           @@//
//@@                                                                                                                     @@//
//@@               ¤ Credits to:                                                                                         @@//
//@@                 * Vexorian, for the dummy.mdx file                                                                  @@//
//@@                 * Jesus4Lyf, for KeyTimers 2                                                                        @@//
//@@                 * TriggerHappy187, for TimedHandles (kinngkingyyk3 changed some stuff though)                       @@//
//@@                                                                                                                     @@//
//@@               Also, many thanks to all of the many helpfull people at TheHelper.net who has helped get              @@//
//@@               this spell working! (kingkingyyk3 and WolfieNoCT especially <img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" class="smilie smilie--sprite smilie--sprite8" alt=":D" title="Big Grin    :D" loading="lazy" data-shortname=":D" />)                                       @@//
//@@                                                                                                                     @@//
//@@                                                                                                                     @@//
//@@               Note: This is my very first fully working, and quite good, spell made completely in JASS.             @@//
//@@               So much feedback, and suggestions are very much welcome, and maybe some tips to make it               @@//
//@@               even better would be nice <img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" class="smilie smilie--sprite smilie--sprite8" alt=":D" title="Big Grin    :D" loading="lazy" data-shortname=":D" />                                                                          @@//
//@@                                                                                                                     @@//
//*************************************************************************************************************************//
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 
globals

    // Effects! Change as you&#039;d like <img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" class="smilie smilie--sprite smilie--sprite2" alt=";)" title="Wink    ;)" loading="lazy" data-shortname=";)" />\\
    
    private constant string EFFECT_C = &quot;Abilities\\Spells\\Demon\\DarkPortal\\DarkPortalTarget.mdl&quot;                // Effect on the caster!
    private constant string EFFECT_1 = &quot;Abilities\\Spells\\Human\\MarkOfChaos\\MarkOfChaosTarget.mdl&quot;              // Effect 200 range from the caster!
    private constant string EFFECT_2 = &quot;Abilities\\Spells\\Orc\\WarStomp\\WarStompCaster.mdl&quot;                      // Effect at the end!
    private constant string DUMMY_EFFECT = &quot;Abilities\\Weapons\\DemolisherFireMissile\\DemolisherFireMissile.mdl&quot;  // Effect on the moving dummy!
    
    // ID&#039;s! Change to the ID&#039;s on your map <img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" class="smilie smilie--sprite smilie--sprite8" alt=":D" title="Big Grin    :D" loading="lazy" data-shortname=":D" />\\
    
    private constant integer SPELL_ID = &#039;0000&#039;          // ID of the spell!
    private constant integer DUMMY_ID = &#039;h000&#039;          // ID of the dummy unit!
    private constant integer LOCUST = &#039;Aloc&#039;            // ID of the &quot;Locust&quot; ability! (Might not need changing)
    private constant integer BUFF_ID = &#039;BTLF&#039;           // ID of the expiration buff on the dummy!
    
    // Other constant integers! Change at will <img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" class="smilie smilie--sprite smilie--sprite7" alt=":p" title="Stick Out Tongue    :p" loading="lazy" data-shortname=":p" />\\
    
    private constant integer DAMAGE_FACTOR = 1
    private constant real RANGE_FACTOR = 15
    private constant integer ANGLES = 17                   // The number of agles the effects will show at! (360/ANGLES)
    private constant attacktype ATTACK_TYPE = ATTACK_TYPE_NORMAL  // Explains itself i think XD
    private constant damagetype DAMAGE_TYPE = DAMAGE_TYPE_NORMAL  //  Same here <img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" class="smilie smilie--sprite smilie--sprite7" alt=":p" title="Stick Out Tongue    :p" loading="lazy" data-shortname=":p" />
endglobals

globals
        
    // Globals! Simply DON&#039;T CHANGE!\\
    
    private player p
    private integer TempStructIndex
    private integer LEVEL

endglobals
    
private struct Data
    unit array du [ANGLES]
    unit cs
    real array pointx [ANGLES]
    real array pointy [ANGLES]
    boolean b
    player p
    group g
    
    static method create takes unit u returns Data
        local Data a = Data.allocate()
        set a.cs = u
        set a.b = false
        set a.p = GetOwningPlayer(a.cs)
        set a.g = CreateGroup()
        set LEVEL = GetUnitAbilityLevel(a.cs,SPELL_ID)
        return a
    endmethod
    
endstruct

        // Some more configurables that needed the struct!\\

    // Damage functions!\\

private function Damage_Small takes nothing returns integer
    return DAMAGE_FACTOR * 10
endfunction

private function Damage_Medium takes nothing returns integer
    return 50 + LEVEL * DAMAGE_FACTOR * 50
endfunction

private function Damage_High takes nothing returns integer
    return LEVEL * DAMAGE_FACTOR * 100
endfunction

    // Range functions!\\

private function Range_Small takes nothing returns real
    return RANGE_FACTOR * 5
endfunction

private function Range_Medium takes nothing returns real
    return RANGE_FACTOR * 10
endfunction

private function Range_High takes nothing returns real
    return RANGE_FACTOR * RANGE_FACTOR
endfunction

        // End of Configuration!\\

private function Spell_Check takes nothing returns boolean
    return GetSpellAbilityId() == SPELL_ID
endfunction

private function GroupEm takes nothing returns boolean
    local Data a = TempStructIndex
    return GetWidgetLife(GetFilterUnit()) &gt; 0.405 and IsUnitEnemy(GetFilterUnit(), a.p) and IsUnitType(GetFilterUnit(), UNIT_TYPE_MAGIC_IMMUNE) == false and IsUnitInGroup(GetFilterUnit(),a.g) == false
endfunction

private function Smaller_GroupEm takes nothing returns boolean
    local Data a = TempStructIndex
    return GetWidgetLife(GetFilterUnit()) &gt; 0.405 and IsUnitEnemy(GetFilterUnit(), a.p) and IsUnitType(GetFilterUnit(), UNIT_TYPE_MAGIC_IMMUNE) == false
endfunction

private function Callback takes nothing returns nothing
    local Data a = TempStructIndex
    local integer i = 0
    loop
    exitwhen i ==16
    call DestroyEffect(AddSpecialEffect(EFFECT_2,GetUnitX(a.du<i>),GetUnitY(a.du<i>)))
    call RemoveUnit(a.du<i>)
    set i = i+1
    endloop
endfunction

private function Move_Dummy takes nothing returns boolean
    local Data a = KT_GetData()
    local real xd
    local real yd
    local integer i = 0
    local unit temp
    local group g
    set p = GetOwningPlayer(a.cs)
    loop
        exitwhen i==16
        set g = CreateGroup()
        set xd = GetUnitX(a.du<i>)
        set yd = GetUnitY(a.du<i>)
        set a.pointx<i> = xd+10*Cos(I2R(i*(360/(ANGLES-1)))*bj_DEGTORAD)
        set a.pointy<i> = yd+10*Sin(I2R(i*(360/(ANGLES-1)))*bj_DEGTORAD)
        set TempStructIndex = a
        call GroupEnumUnitsInRange(g, a.pointx<i>, a.pointy<i>, Range_Small, Filter(function Smaller_GroupEm))
        loop
            set temp = FirstOfGroup(g)
        exitwhen temp == null
            call UnitDamageTarget(a.cs, temp, Damage_Small, true, false, ATTACK_TYPE, DAMAGE_TYPE, null)
            call GroupAddUnit(a.g,temp)
            call GroupRemoveUnit(g,temp)
        endloop
        call DestroyGroup(g)
        call SetUnitX(a.du<i>,a.pointx<i>)
        call SetUnitY(a.du<i>,a.pointy<i>)
        set i = i+1
    endloop
    call GroupClear(a.g)
    set temp = null
    set g = null
    return a.b
endfunction

private function Effects takes nothing returns nothing
    local Data a = Data.create(GetTriggerUnit())
    local real xu = GetUnitX(a.cs)
    local real yu = GetUnitY(a.cs)
    local integer i = 0
    local group g
    local unit temp
    local timer array t
    set p = GetOwningPlayer(a.cs)
    set LEVEL = GetUnitAbilityLevel(GetTriggerUnit(),SPELL_ID)
    call DestroyEffect(AddSpecialEffect(EFFECT_C,xu,yu))
    loop
        exitwhen i&gt;=16
        set g = CreateGroup()
        set a.pointx<i> = xu+200*Cos(I2R(i*(360/(ANGLES-1)))*bj_DEGTORAD)
        set a.pointy<i> = yu+200*Sin(I2R(i*(360/(ANGLES-1)))*bj_DEGTORAD)
        call DestroyEffect(AddSpecialEffect(EFFECT_1,a.pointx<i>,a.pointy<i>))
        set p = GetOwningPlayer(a.cs)
        call GroupEnumUnitsInRange(g, a.pointx<i>, a.pointy<i>,Range_Medium, Filter(function GroupEm))
        loop
            set temp = FirstOfGroup(g)
            exitwhen temp == null
            call UnitDamageTarget(a.cs, temp, Damage_Medium, true, false, ATTACK_TYPE, DAMAGE_TYPE, null)
            call GroupAddUnit(a.g,temp)
            call GroupRemoveUnit(g,temp)
        endloop
        call DestroyGroup(g)
        set a.du<i> = CreateUnit(p,DUMMY_ID,xu,yu,bj_RADTODEG*Atan2(a.pointy<i>-yu,a.pointx<i>-xu))
        set t<i> = CreateTimer()
        call TimerStart(t<i>,2.5,false,function Callback)
        call UnitAddAbility(a.du<i>,LOCUST)
        set i = i+1
    endloop
    call KT_Add(function Move_Dummy,a,.05)
    set p = null
    set temp = null
    set g = null
    call TriggerSleepAction(2.5)
    set a.b = true
    call GroupClear(a.g)
    call DestroyGroup(a.g)
    set p = null
    set temp = null
    call a.destroy()
endfunction

private function init takes nothing returns nothing
    local trigger t=CreateTrigger()
    call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT)
    call TriggerAddCondition(t,Condition(function Spell_Check))
    call TriggerAddAction(t,function Effects)
endfunction
endscope</i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i></i>
 

Rainther

I guess I should write something of value here...
Reaction score
61
I'm not the right person to answer that. I only know how ABC and TimerUtils works and how to use them.
 

kingkingyyk3

Visitor (Welcome to the Jungle, Baby!)
Reaction score
216
ABC is safer than TimerUtils as I know. ABC has handle protection that disable other handle with same id after hashing to access the table. It will store it in game cache when this kind of case happen(ABC v6).

I am busy now, later I will make a solution for it.
 
General chit-chat
Help Users
  • No one is chatting at the moment.

      The Helper Discord

      Staff online

      Members online

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top