• Listen to a special audio message from Bill Roper to the Hive Workshop community (Bill is a former Vice President of Blizzard Entertainment, Producer, Designer, Musician, Voice Actor) 🔗Click here to hear his message!
  • Read Evilhog's interview with Gregory Alper, the original composer of the music for WarCraft: Orcs & Humans 🔗Click here to read the full interview.

[vJASS] pathing problem again :(

Status
Not open for further replies.
Level 10
Joined
May 28, 2011
Messages
455
ive tried knockback system from Coding an efficient knockback and implemented Is Pathable.

But it only work if the knockbacked unit die. can anyone tell me what is the actual problem here and how to solve it?

to knockback unit. we need new x n y offset from its current position. then, if the x n y pathable (walkable) then set the unit position to x n y. so, i guess the problem is the unit itself make the new x n y unpathable. any idea?

Thank you in advance :)
 
If you need to, you can do call SetUnitPathing(u, false) prior to the checks in case the unit itself is causing any false returns.

However, according to this:
But it only work if the knockbacked unit die

It seems like you have a condition that isn't setup properly. Post the code and we'll be able to figure the problem out.
 
Level 10
Joined
May 28, 2011
Messages
455
JASS:
library Knockback initializer Init uses IsPathable

    struct Knockback_Data
        unit u
        real d1
        real d2
        
        real sin
        real cos
        
        real r
        
        string s = ""
        effect e = null
    endstruct

    globals 
        private timer Tim = CreateTimer()
        private Knockback_Data array KnockAr[100]
        private integer KnockTotal = 0
        
        private item I = CreateItem('ciri', 0, 0)
        
        boolexpr filter
    endglobals

    private function Knockback_TreeFilter takes nothing returns boolean
        local integer d = GetDestructableTypeId(GetFilterDestructable())
        return d == 'ATtr' or d == 'BTtw' or d == 'KTtw' or d == 'YTft' or d == 'JTct' or d == 'YTst' or d == 'YTct' or d == 'YTwt' or d == 'JTwt' or d == 'JTwt' or d == 'FTtw' or d == 'CTtr' or d == 'ITtw' or d == 'NTtw' or d == 'OTtw' or d == 'ZTtw' or d == 'WTst' or d == 'LTlt' or d == 'GTsh' or d == 'Xtlt' or d == 'WTtw' or d == 'Attc' or d == 'BTtc' or d == 'CTtc' or d == 'ITtc' or d == 'NTtc' or d == 'ZTtc'
    endfunction
    
    function Knockback_KillTree takes nothing returns nothing
        call KillDestructable(GetEnumDestructable())
    endfunction

    private constant function Interval takes nothing returns real
        return 0.04
    endfunction
    
    private function Knockback_Execute takes nothing returns nothing
        local Knockback_Data kd
        local integer i = 0
        local real x
        local real y
        local integer X
        local integer Y
        local rect r
        local boolexpr b
        
        
        loop
            exitwhen(i >= KnockTotal)
            set kd = KnockAr[i]
            
            if(kd.s != null and kd.s != null) then
                set x = GetUnitX(kd.u)
                set y = GetUnitY(kd.u)
                
                call DestroyEffect(AddSpecialEffect(kd.s, x, y))
                
                set x = x + kd.d1 * kd.cos
                set y = y + kd.d1 * kd.sin
            else
                set x = GetUnitX(kd.u) + kd.d1 * kd.cos
                set y = GetUnitY(kd.u) + kd.d1 * kd.sin
            endif
            
            set X = R2I(x)
            set Y = R2I(y)
            
            if(kd.r != 0) then
                set r = Rect(x - kd.r, y - kd.r, x + kd.r, y + kd.r)
                set b = Filter(function Knockback_TreeFilter)
                call EnumDestructablesInRect(r, b, function Knockback_KillTree)
                call RemoveRect(r)
                call DestroyBoolExpr(b)
            endif
            
            if(IsPathable(X, Y, 5)) then
                call SetUnitX(kd.u, x)
                call SetUnitY(kd.u, y)
            endif
            
            set kd.d1 = kd.d1 - kd.d2
            
            if(kd.d1 <= 0 or not IsPathable(X, Y, 5)) then
                if kd.e != null then
                    call DestroyEffect(kd.e)
                endif
                call PauseUnit(kd.u, false)
                call SetUnitPathing( kd.u, true )
                set KnockAr[i] = KnockAr[KnockTotal -  1]
                set KnockTotal = KnockTotal - 1
                call kd.destroy()
            endif
            
            set i = i + 1
        endloop
        
        if KnockTotal == 0 then
            call PauseTimer(Tim)
        endif
    endfunction

    function KnockbackEx takes unit u, real d, real a, real w, real r, integer t, string s, string p returns Knockback_Data 
        local Knockback_Data kd = Knockback_Data.create()
        local integer q = R2I(w / Interval())
        
        set kd.u = u
        set kd.d1 = 2 * d / (q + 1)
        set kd.d2 = kd.d1 / q
        
        set kd.sin = Sin(a)
        set kd.cos = Cos(a)
        
        set kd.r = r
        
        if(s != "" and s != null) then
            if(t == 2) then
                if(p != "" and p != null) then
                    set kd.e = AddSpecialEffectTarget(s, u, p)
                else
                    set kd.e = AddSpecialEffectTarget(s, u, "chest")
                endif
            elseif t == 1 then
                set kd.s = s
            endif
        endif
        
        call SetUnitPosition(u, GetUnitX(u), GetUnitY(u))
        call PauseUnit(u, true)
        call UnitAddAbility(u, 'Arav')
        call UnitRemoveAbility(u, 'Arav')
        call SetUnitPathing( u, false )
        
        if(KnockTotal <= 0) then
            call TimerStart(Tim, Interval(), true, function Knockback_Execute)
        endif
        
        set KnockTotal = KnockTotal + 1
        set KnockAr[KnockTotal - 1] = kd
        
        return kd
    endfunction

    function Knockback takes unit u, real d, real a, real w returns Knockback_Data
        return KnockbackEx(u, d, a, w, 0, 0, "", "")
    endfunction
    
    private function Init takes nothing returns nothing
        set filter = Filter(function Knockback_TreeFilter)
    endfunction
endlibrary
here is the code. :)
i tried remove the unit path too. no change at all. the problem still there.
 
Last edited:
Did you implement the custom units for the script properly? Also, add a bjdebugmsg in the kd.destroy() portion to see if it accidentally ends too early.

Also make sure that you are inputting the correct values for the function. (make sure that d and w are high enough so that the knockback isn't instant or anything like that)

Does "can" display?
 
Level 10
Joined
May 28, 2011
Messages
455
Did you implement the custom units for the script properly?
I guess. i follow the instructions given and no error display after i saved. besides, i can call the function.

Also, add a bjdebugmsg in the kd.destroy() portion to see if it accidentally ends too early.
lets try that.

Also make sure that you are inputting the correct values for the function
i do. i do stub testing and all the parameters are transferred correctly.
however, my d = 100 and w = 0.5. therefore, my q = 12.5, d1 = 14.8148, and d2 = 1.1851.

(make sure that d and w are high enough so that the knockback isn't instant or anything like that)
high enough? how much? i hate to see the unit knockback more than 1 sec. its too long.

Does "can" display?
"can" display after the knockback unit die. they die like gondar lol
 
Level 10
Joined
May 28, 2011
Messages
455
Also, add a bjdebugmsg in the kd.destroy() portion to see if it accidentally ends too early
Already done, its early as i expected..

Try disabling the pause.
The problem still there :(

debug yourself by using BJDebuMsg everywhere :)
I already do that. cant trace the real problem. :(

Here is the map
 

Attachments

  • Test Knockback Error.w3x
    31.2 KB · Views: 51
Status
Not open for further replies.
Top