HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

Rising_Dusk Effect not working!

03-11-2009, 12:20 PM#1
wraithseeker
Collapse JASS:
scope Warstomp initializer Init

globals
private constant integer SPELL = 'AOws'
private constant real TIME = 0.03
private constant string EFFECT = "MDX\\KnockbackDust.mdx"
private boolexpr b
private constant real STARTSPEED = 1200
private constant real DECREMENT = 10
endglobals

struct data
real x
real y
group g
unit caster
integer i
timer t
real distance
real fx
real speed
real decrement
effect dust

static method create takes nothing returns data
local data d = data.allocate()
set d.g = CreateGroup()
set d.t = NewTimer()
set d.caster = GetTriggerUnit()
set d.x = GetUnitX(d.caster)
set d.y = GetUnitY(d.caster)
set d.i = GetUnitAbilityLevel(d.caster,SPELL)
set d.speed = STARTSPEED
set d.decrement = DECREMENT
call GroupEnumUnitsInRange(d.g,d.x,d.y,100+50*d.i,b)
return d
endmethod

method onDestroy takes nothing returns nothing
call ReleaseTimer(.t)
call DestroyEffect(.dust)
endmethod
endstruct

private function DISTANCE takes integer level returns integer
return level * 250
endfunction

private function Conditions takes nothing returns boolean
    return GetSpellAbilityId() == SPELL
endfunction

private function Check takes nothing returns boolean
    return IsPlayerEnemy(GetOwningPlayer(GetTriggerUnit()), GetOwningPlayer(GetFilterUnit())) and GetWidgetLife(GetFilterUnit()) > 0.405 and not IsUnitType(GetFilterUnit(), UNIT_TYPE_FLYING)
endfunction

private function Move takes nothing returns nothing
local data d = data(GetTimerData(GetExpiredTimer()))
local unit t = GetEnumUnit()
local real ux = GetUnitX(t)
local real uy = GetUnitY(t)
local real angle = Atan2(uy-d.y,ux-d.x)
local real cos = Cos(angle)
local real sin = Sin(angle)
set ux = ux + cos * TIME * d.speed
set uy = uy + sin * TIME * d.speed
call SetUnitPosition(t,ux,uy)
call DestroyEffect(d.dust)
set d.dust = AddSpecialEffectTarget(EFFECT,t,"origin")
endfunction

private function Loop takes nothing returns nothing
local data d = data(GetTimerData(GetExpiredTimer()))
set d.speed = d.speed - d.decrement
set d.distance = d.distance - TIME * d.speed
if d.distance <= 0 then
call d.destroy()
endif
call ForGroup(d.g,function Move)
endfunction

private function Actions takes nothing returns nothing
local data d = data.create()
local unit caster = GetTriggerUnit()
set d.distance = DISTANCE(GetUnitAbilityLevel(d.caster,SPELL))
call SetTimerData(d.t,integer(d))
call TimerStart(d.t,TIME,true,function Loop)
set caster = null
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 Conditions ) )
    call TriggerAddAction( t, function Actions )
    set b = Condition(function Check)
endfunction

endscope

My problem right now is , the effect displays as though there is ... only a little dust effect and not a one straight line meaning it doesn't look complete and when the target has reached his destination , the effect still stays there forever.

More information = reply thread.
03-11-2009, 12:28 PM#2
xombie
You know what...

Collapse JASS:
scope Warstomp initializer Init
// You will notice that I have indented and organized your code. It is no different
// than it was before, it just looks better.
globals
    private constant integer SPELL = 'AOws'
    private constant string EFFECT = "MDX\\KnockbackDust.mdx"
    private boolexpr b
    
    private constant real TIME          = 0.03
    private constant real STARTSPEED    = 1200
    private constant real DECREMENT     = 10
endglobals

struct data
    unit caster
    group g
    effect dust
    timer t

    real x
    real y
    real fx
    real speed
    real decrement
    real distance
    
    integer i   // you should really try to think of better naming conventions, it makes the spell code
                // a heck of a lot easier to follow

    static method create takes nothing returns data
        local data d = data.allocate()
        
        set d.g = CreateGroup()
        set d.t = NewTimer()
        set d.caster = GetTriggerUnit()
        set d.x = GetUnitX(d.caster)
        set d.y = GetUnitY(d.caster)
        set d.i = GetUnitAbilityLevel(d.caster,SPELL)
        set d.speed = STARTSPEED
        set d.decrement = DECREMENT
        
        call GroupEnumUnitsInRange(d.g,d.x,d.y,100+50*d.i,b)
        return d
    endmethod

    method onDestroy takes nothing returns nothing
        call ReleaseTimer(.t)
        call DestroyEffect(.dust)
    endmethod
endstruct

private function DISTANCE takes integer level returns integer
    return level * 250
endfunction

private function Conditions takes nothing returns boolean
    return GetSpellAbilityId() == SPELL
endfunction

private function Check takes nothing returns boolean
    return IsPlayerEnemy(GetOwningPlayer(GetTriggerUnit()), GetOwningPlayer(GetFilterUnit())) and GetWidgetLife(GetFilterUnit()) > 0.405 and not IsUnitType(GetFilterUnit(), UNIT_TYPE_FLYING)
endfunction

private function Move takes nothing returns nothing
    local data d = data(GetTimerData(GetExpiredTimer()))
    local unit t = GetEnumUnit()
    local real ux = GetUnitX(t)
    local real uy = GetUnitY(t)
    local real angle = Atan2(uy-d.y,ux-d.x)
    local real cos = Cos(angle)
    local real sin = Sin(angle)
    
    set ux = ux + cos * TIME * d.speed
    set uy = uy + sin * TIME * d.speed
    call SetUnitPosition(t,ux,uy)
    
    call DestroyEffect(d.dust)
    set d.dust = AddSpecialEffectTarget(EFFECT,t,"origin")
endfunction

private function Loop takes nothing returns nothing
    local data d = data(GetTimerData(GetExpiredTimer()))
    
    set d.speed = d.speed - d.decrement
    set d.distance = d.distance - TIME * d.speed
    if d.distance <= 0 then
        call d.destroy()
    endif
    
    call ForGroup(d.g,function Move)
endfunction

private function Actions takes nothing returns nothing
    local data d = data.create()
    local unit caster = GetTriggerUnit()
    
    set d.distance = DISTANCE(GetUnitAbilityLevel(d.caster,SPELL))
    call SetTimerData(d.t,integer(d))
    call TimerStart(d.t,TIME,true,function Loop)
    
    set caster = null
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 Conditions ) )
    call TriggerAddAction( t, function Actions )
    set b = Condition(function Check)
endfunction

endscope

Thank you baby jesus!

Okay, what exactly are ya trying to do here?
03-11-2009, 12:42 PM#3
wraithseeker
Er... well solution? And thanks! I was in a hurry to post this so.... pardon me.
03-11-2009, 12:43 PM#4
xombie
Is this supposed to be like an area of effect knock back spell?
03-11-2009, 12:54 PM#5
wraithseeker
Yes, a warstomp which basically knocks unit away by a x distance. The effects are the problem , spell's fine.
03-11-2009, 01:08 PM#6
xombie
Quote:
Originally Posted by wraithseeker
Collapse JASS:
private function Move takes nothing returns nothing
    local data d = data(GetTimerData(GetExpiredTimer()))
    local unit t = GetEnumUnit()
    local real ux = GetUnitX(t)
    local real uy = GetUnitY(t)
    local real angle = Atan2(uy-d.y,ux-d.x)
    local real cos = Cos(angle)
    local real sin = Sin(angle)
    
    set ux = ux + cos * TIME * d.speed
    set uy = uy + sin * TIME * d.speed
    call SetUnitPosition(t,ux,uy)
    
    call DestroyEffect(d.dust)
    set d.dust = AddSpecialEffectTarget(EFFECT,t,"origin")
endfunction

You only have one single effect variable that handles an entire group's worth of special effects. I think what should happen here is the very last enumerated unit will always be given the effect (the others are destroyed almost immediately).

Quote:
Originally Posted by wraithseeker
Collapse JASS:
private function Loop takes nothing returns nothing
    local data d = data(GetTimerData(GetExpiredTimer()))
    call ForGroup(d.g,function Move) // move this here

    set d.speed = d.speed - d.decrement
    set d.distance = d.distance - TIME * d.speed
    if d.distance <= 0 then
        // the reason your effect would last forever is because you were destroying the struct
        // before it was getting a chance to do call DestroyEffect(d.dust)
        call d.destroy()
    endif
endfunction
03-11-2009, 01:12 PM#7
moyack
Why don't you use this??
03-11-2009, 01:18 PM#8
xombie
moyack, you can't learn anything if you are only referenced to other systems. He is doing this for the sake of learning.
03-11-2009, 01:40 PM#9
wraithseeker
Quote:
Originally Posted by xombie
You only have one single effect variable that handles an entire group's worth of special effects. I think what should happen here is the very last enumerated unit will always be given the effect (the others are destroyed almost immediately).

So , what am I supposed to fix other then the forgroup which has been done.

I took Dusk~ knockback system as a reference.

Code's here

Collapse JASS:
//***************************************************************************************************************
//*                                                                                                             *
//*                                         K N O C K B A C K                                                   *
//*                                            Actual Code                                                      *
//*                                               v1.02                                                         *
//*                                                                                                             *
//*                                          By: Rising_Dusk                                                    *
//*                                                                                                             *
//***************************************************************************************************************

library Knockback initializer KnockbackSystemInit
globals
    //*********************************************************
    //* These are the configuration constants for the system
    //*
    //* EffectLocation:     Where on the unit the effect attaches
    //* EffectPath_Water:   What special effect to attach over water
    //* EffectPath_Ground:  What special effect to attach over ground
    //* Dest_Radius:        Radius around which destructs die
    //*
    private constant string EffectLocation         = "origin"
    private constant string EffectPath_Water       = "MDX\\KnockbackWater.mdx"
    private constant string EffectPath_Ground      = "MDX\\KnockbackDust.mdx"
    private constant real Dest_Radius              = 180.
    
    //*********************************************************
    //* These are static constants used by the system and shouldn't be changed
    //*
    //* Timer:              The timer that runs all of the effects for the spell
    //* Counter:            The counter for how many KB instances exist
    //* Knockers:           The array of all struct instances that exist
    //* TimerInterval:      The interval for the timer that gets run
    //* Boolexpr:           The boolean expression used for finding destructs
    //* DestRect:           The rect used to check for destructables
    //*
    private timer Timer                            = CreateTimer()
    private integer Counter                        = 0
    private integer array Knockers
    private constant real TimerInterval            = 0.05
    private boolexpr Boolexpr
    private rect DestRect                          = Rect(0,0,1,1)
    
    //* Temporary variables used by the system
    private real Temp1
    private real Temp2
endglobals

//*********************************************************
//* Functions for the destructable destruction
private function KillDests_Check takes nothing returns boolean
    local real x = GetDestructableX(GetFilterDestructable())
    local real y = GetDestructableY(GetFilterDestructable())
    return (Temp1-x)*(Temp1-x) + (Temp2-y)*(Temp2-y) <= Dest_Radius*Dest_Radius
endfunction

private function KillDests takes nothing returns nothing
    call KillDestructable(GetEnumDestructable())
endfunction

//*********************************************************
//* Struct for the system, I recommend leaving it alone
private struct knocker
    unit Target
    effect KBEffect
    integer FXMode
    boolean KillDest
    real Decrement
    real Speed
    real SinA
    real CosA
    
    public method checkterrain takes knocker n returns integer
        local real x = GetUnitX(n.Target)
        local real y = GetUnitY(n.Target)
        if IsTerrainPathable(x, y, PATHING_TYPE_FLOATABILITY) then
            return 1
        elseif not IsTerrainPathable(x, y, PATHING_TYPE_WALKABILITY) then
            return 2
        endif
        return 0
    endmethod
    static method create takes unit targ, real angle, real startspeed, real decrement, boolean killDestructables returns knocker
        local knocker n = knocker.allocate()
        set n.Target = targ
        set n.FXMode = n.checkterrain(n)
        if n.FXMode == 1 then
            set n.KBEffect = AddSpecialEffectTarget(EffectPath_Ground, n.Target, EffectLocation)
        elseif n.FXMode == 2 then
            set n.KBEffect = AddSpecialEffectTarget(EffectPath_Water, n.Target, EffectLocation)
        debug else
            debug call BJDebugMsg("System Error (On Create): Unknown Terrain Type")
        endif
        set n.KillDest = killDestructables
        set n.Decrement = decrement
        set n.Speed = startspeed
        set n.SinA = Sin(angle)
        set n.CosA = Cos(angle)
        return n
    endmethod
    private method onDestroy takes nothing returns nothing
        call DestroyEffect(this.KBEffect)
    endmethod
endstruct

//******************************************************************************
//* The system code itself.

private function Update takes nothing returns nothing
    local unit u
    local rect r
    local knocker n = 0
    local integer i = Counter - 1
    local integer j = 0
    local integer mode
    local real speed
    local real xi
    local real yi
    local real xf
    local real yf
    
    loop
        exitwhen i < 0
        set n = Knockers[i]
        set u = n.Target
        set mode = n.FXMode
        
        set xi = GetUnitX(u)
        set yi = GetUnitY(u)
        
        if n.Speed <= 0 then
            call n.destroy()
            set Counter = Counter - 1
            if Counter < 0 then
                call PauseTimer(Timer)
                set Counter = 0
            else
                set Knockers[i] = Knockers[Counter]
            endif
        else
            set xf = xi + (n.Speed) * n.CosA
            set yf = yi + (n.Speed) * n.SinA
            call SetUnitPosition(u, xf, yf)
            set n.FXMode = n.checkterrain(n)
            if n.FXMode == 1 and mode == 2 then
                call DestroyEffect(n.KBEffect)
                set n.KBEffect = AddSpecialEffectTarget(EffectPath_Ground, n.Target, EffectLocation)
            elseif n.FXMode == 2 and mode == 1 then
                call DestroyEffect(n.KBEffect)
                set n.KBEffect = AddSpecialEffectTarget(EffectPath_Water, n.Target, EffectLocation)
            debug elseif n.FXMode == 0 then
                debug call BJDebugMsg("System Error (In Update): Unknown Terrain Type")
            endif
            set n.Speed = n.Speed - n.Decrement
            
            //* Destroy destructables if desired
            if n.KillDest then
                set Temp1 = GetUnitX(u)
                set Temp2 = GetUnitY(u)
                call SetRect(DestRect, xf-Dest_Radius, yf-Dest_Radius, xf+Dest_Radius, yf+Dest_Radius)
                call EnumDestructablesInRect(DestRect, Boolexpr, function KillDests)
            endif
        endif
        set i = i - 1
    endloop
    
    set u = null
endfunction

function KnockbackStop takes unit targ returns boolean
    local integer i = Counter - 1
    local knocker n = 0
    local boolean b = false
    loop
        exitwhen i < 0
        set n = Knockers[i]
        if n.Target == targ then
            call n.destroy(n)
            set Counter = Counter - 1
            if Counter < 0 then
                call PauseTimer(Timer)
                set Counter = 0
            else
                set Knockers[i] = Knockers[Counter]
            endif
            set b = true
        endif
        set i = i - 1
    endloop
    return b
endfunction

function IsKnockedBack takes unit targ returns boolean
    local integer i = Counter - 1
    local knocker n = 0
    loop
        exitwhen i < 0
        set n = Knockers[i]
        if n.Target == targ then
            return true
        endif
        set i = i - 1
    endloop
    return false
endfunction

function KnockbackTarget takes unit targ, real angle, real startspeed, real decrement, boolean killDestructables returns boolean
    local knocker n = 0
    
    //* Protect users from themselves
    if decrement == 0 or startspeed == 0 or targ == null then
        debug call BJDebugMsg("System Error: Invalid Starting Conditions")
        return false
    endif
    set n = knocker.create(targ, angle*0.01745328, startspeed*TimerInterval, decrement*TimerInterval, killDestructables)
    if Counter == 0 then
        call TimerStart(Timer, TimerInterval, true, function Update)
    endif
    set Knockers[Counter] = n
    set Counter = Counter + 1
    return true
endfunction

private function KnockbackSystemInit takes nothing returns nothing
    set Boolexpr = Condition(function KillDests_Check)
endfunction

public function InitTrig takes nothing returns nothing
endfunction
endlibrary
03-11-2009, 01:50 PM#10
xombie
Notice how he has a struct that handles each individual unit that is being knocked back?
03-11-2009, 02:32 PM#11
wraithseeker
Like how? What? I don't understand this whole thing .... He has a struct like I had which had almost all same identical variables and the only thing that was different was he looped using arrays instead of using TimerUtils.
03-11-2009, 02:35 PM#12
xombie
No, see.

Collapse JASS:
function KnockbackTarget takes unit targ, real angle, real startspeed, real decrement, boolean killDestructables returns boolean
    local knocker n = 0
    
    //* Protect users from themselves
    if decrement == 0 or startspeed == 0 or targ == null then
        debug call BJDebugMsg("System Error: Invalid Starting Conditions")
        return false
    endif
    set n = knocker.create(targ, angle*0.01745328, startspeed*TimerInterval, decrement*TimerInterval, killDestructables)
    if Counter == 0 then
        call TimerStart(Timer, TimerInterval, true, function Update)
    endif
    set Knockers[Counter] = n
    set Counter = Counter + 1
    return true
endfunction

He creates a struct for every unit that is being knocked back, you only create one that tries to handle all instances.
03-11-2009, 02:39 PM#13
moyack
Quote:
Originally Posted by xombie
moyack, you can't learn anything if you are only referenced to other systems. He is doing this for the sake of learning.
xombie, he can read the code and learn how to do it, but in the other hand, he can use it and make his life easier.

@wraithseeker: You can use my library and just start the effect, it will take care of stopping and cleaning it properly.
03-11-2009, 02:46 PM#14
xombie
Quote:
Originally Posted by moyack
xombie, he can read the code and learn how to do it, but in the other hand, he can use it and make his life easier.

As you can see, he has read the code, and still does not understand it - I do not like referencing people elsewhere to find help because when I was trying to learn, sometimes the code was a little too much for me to take in all at once
03-11-2009, 03:18 PM#15
wraithseeker
Some Off Thread questions in which my other spell invoked some extra problems with this SFX,

Collapse JASS:
scope FlyStrike initializer Init

globals
    private constant integer FLYID = 'Amrf'
    private constant integer SPELL = 'A000'
    private constant integer STUN = 'A001'
    private constant real TIME = 0.03
    private constant real SPEED = 1000
    private constant real DECREMENT = 10
    private boolexpr Checker
    private constant string EFFECT = "MDX\\KnockbackDust.mdx"
    private constant real DISTANCE = 450
    private data Var
endglobals



private struct data
    unit caster
    real cx
    real cy
    real tx
    real ty
    timer fly
    timer knock
    location target
    group g
    real distance
    real decrement
    real speed
    effect dust


static method create takes nothing returns data
    local data d = data.allocate()
    local unit dummy 
    set d.caster = GetTriggerUnit()
    set d.cx = GetUnitX(d.caster)
    set d.cy = GetUnitY(d.caster)
    set d.g = CreateGroup()
    set dummy = CreateUnit(GetOwningPlayer(d.caster),'hfoo',d.cx,d.cy,GetUnitFacing(d.caster))
    set d.target = GetSpellTargetLoc()
    set d.tx = GetLocationX(d.target)
    set d.ty = GetLocationY(d.target)
    set d.fly = NewTimer()
    set d.knock = NewTimer()
    set d.distance = DISTANCE
    set d.decrement = DECREMENT
    set d.speed = SPEED
    call UnitAddAbility(dummy,STUN)
    call IssueTargetOrder(dummy,"thunderbolt",d.caster)
    call UnitApplyTimedLife(dummy,'BTLF',3)
    call SetUnitPathing(d.caster,false)
    call UnitAddAbility(d.caster,FLYID)
    call UnitRemoveAbility(d.caster,FLYID)
    return d
endmethod

method onDestroy takes nothing returns nothing
call ReleaseTimer(.knock)
call DestroyEffect(.dust)
endmethod
    endstruct

private function Conditions takes nothing returns boolean
    return GetSpellAbilityId() == SPELL
endfunction

private function Check takes nothing returns boolean
    local data d = Var
    local unit u = GetEnumUnit()
    return IsUnitEnemy(d.caster, GetOwningPlayer(u)) and GetFilterUnit() != d.caster
endfunction

private function Damage takes nothing returns nothing
    local data d = data(GetTimerData(GetExpiredTimer()))
    local unit u = GetEnumUnit()
    call UnitDamageTarget(d.caster,u, 200, false, false, ATTACK_TYPE_HERO, DAMAGE_TYPE_NORMAL, WEAPON_TYPE_WHOKNOWS)
endfunction

private function Push takes nothing returns nothing
    local data d = data(GetTimerData(GetExpiredTimer()))
    local unit t = GetEnumUnit()
    local real ux = GetUnitX(t)
    local real uy = GetUnitY(t)
    local real angle = Atan2(uy-d.cy,ux-d.cx)
    local real cos = Cos(angle)
    local real sin = Sin(angle)
    set ux = ux + cos * TIME * SPEED
    set uy = uy + sin * TIME * SPEED
    call SetUnitPosition(t,ux,uy)
    call DestroyEffect(d.dust)
    set d.dust = AddSpecialEffectTarget(EFFECT,t,"origin")
endfunction

private function Knock takes nothing returns nothing
    local data d = data(GetTimerData(GetExpiredTimer()))
    set d.speed = d.speed - d.decrement
    set d.distance = d.distance - TIME * SPEED
    if d.distance <= 0 then
    call d.destroy()
    endif
    call ForGroup(d.g,function Push)
endfunction

private function Kill takes nothing returns nothing
    local data d = data(GetTimerData(GetExpiredTimer()))
    set Var = d
    call GroupEnumUnitsInRange(d.g,d.tx,d.ty,300,Checker)
    call SetTimerData(d.knock,integer (d))
    call TimerStart(d.knock,TIME,true,function Knock)
    call ReleaseTimer(d.fly)
    call ForGroup(d.g,function Damage)
endfunction

private function Down takes nothing returns nothing
    local data d = data(GetTimerData(GetExpiredTimer()))
    call SetTimerData(d.fly,integer (d))
    call SetUnitAnimation(d.caster,"attack slam")
    call SetUnitPathing(d.caster,true)
    call TimerStart(d.fly,0.7,false,function Kill)
endfunction

private function Fly takes nothing returns nothing
    local data d = data(GetTimerData(GetExpiredTimer()))
    call SetUnitX(d.caster,d.tx)
    call SetUnitY(d.caster,d.ty)
    set d.cx = GetUnitX(d.caster)
    set d.cy = GetUnitY(d.caster)
    call SetUnitFlyHeight(d.caster,0,3000)
    call SetTimerData(d.fly,integer (d))
    call TimerStart(d.fly,1,false,function Down)
endfunction

private function Actions takes nothing returns nothing
    local data d = data.create()
    call SetTimerData(d.fly,integer (d))
    call SetUnitFlyHeight(d.caster,999999,3000)
    call TimerStart(d.fly,1.5,false,function Fly)
endfunction

//===========================================================================
private function Init takes nothing returns nothing
    local trigger t = CreateTrigger()
    call TriggerRegisterAnyUnitEventBJ( t, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddAction( t, function Actions )
    call TriggerAddCondition(t,Condition(function Conditions))
    set Checker = Condition(function Check)
endfunction

endscope

Why.... Why.. does this have synax error.

undefined type data
cannot convert null to integer
cannot convert integer to null.

Next spell.... the old Dash..

Collapse JASS:
scope Dash initializer Init

globals
    private constant integer SPELL = 'A003'
    private constant real TIME = 0.03
    private constant real SPEEDCASTER = 1500
    private constant real SPEEDTARGET = 1200
    private constant real KnockDistance = 500
    private constant real DECREMENTCASTER = 20
    private constant real DECREMENTTARGET = 10
    private constant string EFFECT = "MDX\\KnockbackDust.mdx"
    private boolexpr Check
    private data Var
endglobals

private function DISTANCE takes integer level returns integer
    return level * 250
endfunction

private struct data
    unit caster
    unit target
    real cos
    real sin
    real angle
    real distance
    timer t
    timer h
    group g
    real casterspeed
    real targetspeed
    real casterdecrement
    real targetdecrement
    effect dust

   

static method create takes nothing returns data
    local data d = data.allocate()
    set d.caster = GetTriggerUnit()
    set d.target = GetSpellTargetUnit()
    set d.t = NewTimer()
    set d.h = NewTimer()
    set d.distance = DISTANCE(GetUnitAbilityLevel(d.caster,SPELL))
    set d.g = CreateGroup()
    set d.casterspeed = SPEEDCASTER 
    set d.targetspeed = SPEEDTARGET
    set d.casterdecrement = DECREMENTCASTER
    set d.targetdecrement = DECREMENTTARGET
    return d
endmethod

method onDestroy takes nothing returns nothing
    call ReleaseTimer(.h)
    call DestroyEffect(.dust)
endmethod
endstruct

private function Conditions takes nothing returns boolean
    return GetSpellAbilityId() == SPELL
endfunction

private function KnockCheck takes nothing returns boolean
    local data d = Var
    return GetFilterUnit() != d.caster and GetFilterUnit() != d.target
endfunction

private function Knock takes nothing returns nothing
    local data d = data(GetTimerData(GetExpiredTimer()))
    local real cx = GetUnitX(d.caster)
    local real cy = GetUnitY(d.caster)
    local real tx = GetUnitX(d.target)
    local real ty = GetUnitY(d.target)
    local real angle = Atan2(ty-cy,tx-cx)
    local real sin = Sin(angle)
    local real cos = Cos(angle)
    set tx = tx + cos * TIME * SPEEDTARGET
    set ty = ty + sin * TIME * SPEEDTARGET
    call SetUnitX(d.target,tx)
    call SetUnitY(d.target,ty)
    call DestroyEffect(d.dust)
    set d.dust = AddSpecialEffectTarget(EFFECT,d.target, "origin")
    set d.targetspeed = d.targetspeed - d.targetdecrement
    set d.distance = d.distance - TIME * SPEEDTARGET
    if d.distance <= 0 then
        call d.destroy()
    endif
endfunction

private function Move takes nothing returns nothing
    local data d = data(GetTimerData(GetExpiredTimer()))
    local real cx = GetUnitX(d.caster)
    local real cy = GetUnitY(d.caster)
    local real tx = GetUnitX(d.target)
    local real ty = GetUnitY(d.target)
    local real angle = Atan2(ty-cy,tx-cx)
    local real sin = Sin(angle)
    local real cos = Cos(angle)
    local unit u
    local real x
    local real y
    local real angles
    local real sins
    local real coss
    set cx = cx + cos * TIME * SPEEDCASTER
    set cy = cy + sin * TIME * SPEEDCASTER
    call SetUnitX(d.caster,cx)
    call SetUnitY(d.caster,cy)
    set Var = d
    call GroupEnumUnitsInRange(d.g,cx,cy,180,Check)
    loop
        set u = FirstOfGroup(d.g)
    exitwhen u == null
        set x = GetUnitX(u)
        set y = GetUnitY(u)
        set angles = Atan2(y-cy,x-cx)
        set sins = Sin(angles)
        set coss = Cos(angles)
        set x = x + coss * TIME * SPEEDCASTER
        set y = y + sins * TIME * SPEEDCASTER
        call SetUnitX(u,x)
        call SetUnitY(u,y)
        call DestroyEffect(d.dust)
        set d.dust = AddSpecialEffectTarget(EFFECT,d.caster, "origin")
        call GroupRemoveUnit(d.g,u)
        endloop
        set d.casterspeed = d.casterspeed - d.casterdecrement
    if SquareRoot((cx - tx) * (cx - tx) + (cy - ty) * (cy - ty)) <= 128 then
        call SetUnitAnimation(d.caster, "attack slam alternate")
        call SetUnitAnimation(d.target, "DEATH")
        call ReleaseTimer(d.t)
        call DestroyEffect(d.dust)
        call SetTimerData(d.h,integer (d))
        call TimerStart(d.h,0.03,true,function Knock)
    endif
endfunction

private function Actions takes nothing returns nothing
    local data d = data.create()
    call SetTimerData(d.t,integer (d))
    call TimerStart(d.t,0.03,true,function Move)
endfunction

//===========================================================================
private function Init takes nothing returns nothing
    local trigger t = CreateTrigger()
    call TriggerRegisterAnyUnitEventBJ( t, EVENT_PLAYER_UNIT_SPELL_EFFECT)
    call TriggerAddAction( t, function Actions)
    call TriggerAddCondition(t,Condition(function Conditions))
    set Check = Condition(function KnockCheck)
endfunction

endscope

Same amount of synax error as above , 3 with all the data var.

For the relevant to this thread, so I need to have another struct which have all the things which I need for each unit , instead of trying to merge 2 structs together? meaning I have to do another private struct knock and then etc...