Knockback system

Viikuna

No Marlo no game.
Reaction score
265
One timer and struct array because its faster + it leaves you more instances of TimerUtils to be used where it is really needed.

I didnt see any reason why effect dont work. Add some debug msges to find the problem.

edit. That just how to calculate angle and sin and cos. Are you still looking answer for that? I think I missed some posts..

Ok, A is some point. Ax and Ay are its x and y coordinates. A is also the point where your attacking unit is standing. The other point, B, is where your 'soon to be knockbacked' unit is standing. Bx and By are his coordinates. Now when unit standing in point A, attacks and knocks unit standing in point B, you calculate the direction where that knocked unit must slide. dx and dy are distance in x coordinates and distance in y coordinates. You can use Atan2 to get angle, and SquareRoot(dx*dx+dy*dy) to get distance between A and B.

its just some math. ( Damn that Bolded text looks ugly :/ )
 

wraithseeker

Tired.
Reaction score
122
Just posting so you won't get flamed for double posting , I edited my above code about the angles.

Did a DebugMsg on the Dust rock effect , it never runs at all.
 

Kenny

Back for now.
Reaction score
202
JASS:
library Knockback initializer Init requires BoundSentinel, TimerUtils, DestructableLib, IsTerrainWalkable

globals
    private constant real TIME = 0.03
    private constant string GROUND = "MDX\\Dust.mdx"
    private constant string WATER = "MDX\\SlideWater.mdx"
    private constant string COLLISION = "MDX\\DustAndRocks.mdx"
    private constant string ATTACHPOINT = "origin"
    private constant real RADIUS = 180.00
    private rect TreeRect = null
    private boolexpr TreeCheck = null
endglobals

private function CheckTrees takes nothing returns boolean
    if IsDestructableTree(GetFilterDestructable()) then
        return true
    endif
    return false
endfunction

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

private struct Knock
    unit source
    unit target
    real x
    real y
    real cos
    real sin
    real speed
    real decrement
    timer Timer
    effect effects
    boolean Terrain
    integer EffectMode
    boolean Trees
    
    public method TerrainCheck takes Knock d returns integer
        local real x = GetUnitX(d.target)
        local real y = GetUnitY(d.target)

        if IsTerrainWalkable(x + 50.00 * d.cos,y + 50.00 * d.sin) == false then
            return 3
        else
            if IsTerrainPathable(x,y,PATHING_TYPE_FLOATABILITY) then
                return 1
            elseif not IsTerrainPathable(x,y,PATHING_TYPE_WALKABILITY) then
                return 2
            endif
        endif            

        return 0
    endmethod

    static method create takes unit source, unit target, real angle, real speed, real decrement, boolean KillTree returns Knock
        local Knock d = Knock.allocate()
        local real x
        local real y
        
        set d.source = source
        set d.target = target
        set d.Trees = KillTree
        set x = GetUnitX(d.target)
        set y = GetUnitY(d.target)
        set d.speed = speed * TIME
        set d.decrement = decrement * TIME
        set d.sin = Sin(angle)
        set d.cos = Cos(angle)
        set d.Timer = NewTimer()
        set d.EffectMode = d.TerrainCheck(d)
        
        if d.EffectMode == 1 then
            set d.effects = AddSpecialEffectTarget(GROUND,d.target,ATTACHPOINT)
        elseif d.EffectMode == 2 then
            set d.effects = AddSpecialEffectTarget(WATER,d.target,ATTACHPOINT)
        elseif d.EffectMode == 3 then
            set d.effects = AddSpecialEffectTarget(COLLISION,d.target,ATTACHPOINT)
        endif

        return d
    endmethod
    
    method onDestroy takes nothing returns nothing
        call DestroyEffect(.effects)
        call ReleaseTimer(.Timer)
    endmethod

endstruct

private function Update takes nothing returns nothing
    local Knock d = Knock(GetTimerData(GetExpiredTimer()))
    local real sx = GetUnitX(d.target)
    local real sy = GetUnitY(d.target)
    local real x = sx + d.speed * d.cos
    local real y = sy + d.speed * d.sin
    local integer mode = d.EffectMode
    
    if d.speed <= 0.00 then
        call d.destroy()
    endif
    
    if d.Trees == true then
        call SetRect(TreeRect,sx-RADIUS,sy-RADIUS,sx+RADIUS,sy+RADIUS)
        call EnumDestructablesInRect(TreeRect,TreeCheck,function Trees)
    endif
        
    call SetUnitPosition(d.target,x,y)
    set d.EffectMode = d.TerrainCheck(d)
    
    if d.EffectMode == 1 and (mode == 2 or mode == 3) then
        call DestroyEffect(d.effects)
        set d.effects = AddSpecialEffectTarget(GROUND,d.target,ATTACHPOINT)
    elseif d.EffectMode == 2 and (mode == 1 or mode == 3) then
        call DestroyEffect(d.effects)
        set d.effects = AddSpecialEffectTarget(WATER,d.target,ATTACHPOINT)
    elseif d.EffectMode == 3 and (mode == 1 or mode == 2) then
        call DestroyEffect(d.effects)
        set d.effects = AddSpecialEffectTarget(COLLISION,d.target,ATTACHPOINT)
    endif
    
    set d.speed = d.speed - d.decrement
endfunction

function KnockbackTarget takes unit source, unit target, real angle, real speed, real decrement, boolean KillTree returns boolean
    local Knock d = 0
    
    if target == null or source == null or speed == null or decrement == null then
        call BJDebugMsg("Invalid Values!")
        return false
    endif
    
    set d = Knock.create(source,target,angle,speed,decrement,KillTree)
    
    call SetTimerData(d.Timer,d)
    call TimerStart(d.Timer,TIME,true,function Update)
    
    return true
endfunction

private function Init takes nothing returns nothing
    set TreeRect = Rect(0,0,1,1)
    set TreeCheck = Filter(function CheckTrees)
endfunction

endlibrary


The rocks show now.
 

Viikuna

No Marlo no game.
Reaction score
265
No need for method TerrainCheck to take Knock d, just use this.member or just .member
 

wraithseeker

Tired.
Reaction score
122
@KENNY!
Mind if you highlight or make the line stand out which you added? Because I added a extra parathesis.

Ok, A is some point. Ax and Ay are its x and y coordinates. A is also the point where your attacking unit is standing. The other point, B, is where your 'soon to be knockbacked' unit is standing. Bx and By are his coordinates. Now when unit standing in point A, attacks and knocks unit standing in point B, you calculate the direction where that knocked unit must slide. dx and dy are distance in x coordinates and distance in y coordinates. You can use Atan2 to get angle, and SquareRoot(dx*dx+dy*dy) to get distance between A and B.

Is A a location or a Real? How can A be at 2 points? Same for B. What is the difference between BX BY and DX DY.

Vikkuna I wasn't talking about knocking back unit , I was talking about bouncing back units , or am I wrong that the thing that you are posting is related to bouncing units?
 

Kenny

Back for now.
Reaction score
202
JASS:
library Knockback initializer Init requires BoundSentinel, TimerUtils, DestructableLib, IsTerrainWalkable // <-- IsTerrainWalkable


Requires IsTerrainWalkable. :p

And (but not as important):

JASS:
public method TerrainCheck takes Knock d returns integer
        local real x = GetUnitX(d.target)
        local real y = GetUnitY(d.target)

        if IsTerrainWalkable(x + 50.00 * d.cos,y + 50.00 * d.sin) == false then
            return 3
        else
            if IsTerrainPathable(x,y,PATHING_TYPE_FLOATABILITY) then
                return 1
            elseif not IsTerrainPathable(x,y,PATHING_TYPE_WALKABILITY) then
                return 2
            endif
        endif            

        return 0
    endmethod
 

Viikuna

No Marlo no game.
Reaction score
265
I was talking about bouncing back units

Oh, sorry, I was talking about something different. Sorry that I confused you.

Bouncing back you need some vector math maybe.. I will see if I can find some bouncing formula.

You need to check where the terrain is Pathable and then do some complicate vector math and add those little vectors to units speed vector.

See this image:
View attachment BounceFromACliff.bmp

You need someone who is better in math than me to explain how this is done.
 

wraithseeker

Tired.
Reaction score
122
Well forget about the issue then , I think it needs a physis system to do that.... right now , I want to know why does my IsTerrainWalkable checks only for cliffs but not for units.

JASS:
//Formula to calculate Distance = -1 * V * V / (2 * A / Interval)  Where variable V is speed and A is decrement.//
//                            Note! V must be positive and A must be negative!!!!                             //
library Knockback initializer Init requires BoundSentinel, TimerUtils, DestructableLib, IsTerrainWalkable

globals
    private constant real TIME = 0.03
    private constant string GROUND = "MDX\\Dust.mdx"
    private constant string WATER = "MDX\\SlideWater.mdx"
    private constant string COLLISION = "MDX\\DustAndRocks.mdx"
    private constant string ATTACHPOINT = "origin"
    private constant real RADIUS = 180
    private rect TreeRect
    private boolexpr TreeCheck
endglobals

private function CheckTrees takes nothing returns boolean
    if IsDestructableTree(GetFilterDestructable()) then
        return true
    endif
    return false
endfunction

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

private struct Knock
    unit source
    unit target
    real x
    real y
    real cos
    real sin
    real speed
    real decrement
    timer Timer
    effect effects
    boolean Terrain
    integer EffectMode
    boolean Trees
    boolean AllowMove
    
    public method TerrainCheck takes Knock d returns integer
        local real x = GetUnitX(d.target)
        local real y = GetUnitY(d.target)

        if IsTerrainWalkable(x + 50.00 * d.cos,y + 50.00 * d.sin) == false then
            return 3
        else
            if IsTerrainPathable(x,y,PATHING_TYPE_FLOATABILITY) then
                return 1
            elseif not IsTerrainPathable(x,y,PATHING_TYPE_WALKABILITY) then
                return 2
            endif
        endif 
        return 0
        endmethod

static method create takes unit source, unit target, real angle, real speed, real decrement, boolean KillTree, boolean Allowmove returns Knock
    local Knock d = Knock.allocate()
    local real x
    local real y
    set d.source = source
    set d.target = target
    set d.Trees = KillTree
    set d.AllowMove = Allowmove
    set x = GetUnitX(d.target)
    set y = GetUnitY(d.target)
    set d.speed = speed * TIME
    set d.decrement = decrement * TIME
    set d.sin = Sin(angle)
    set d.cos = Cos(angle)
    set d.Timer = NewTimer()
    set d.EffectMode = d.TerrainCheck(d)
    if d.EffectMode == 1 then
        set d.effects = AddSpecialEffectTarget(GROUND,d.target,ATTACHPOINT)
    endif
    if d.EffectMode == 2 then
        set d.effects = AddSpecialEffectTarget(WATER,d.target,ATTACHPOINT)
    endif
    if d.EffectMode == 3 then
     set d.effects = AddSpecialEffectTarget(COLLISION,d.target,ATTACHPOINT)
    endif
    return d
    endmethod
    
method onDestroy takes nothing returns nothing
    call DestroyEffect(this.effects)
    call ReleaseTimer(this.Timer)
    endmethod
        endstruct

private function Update takes nothing returns nothing
    local Knock d = Knock(GetTimerData(GetExpiredTimer()))
    local unit u = d.target
    local real sx = GetUnitX(u)
    local real sy = GetUnitY(u)
    local real x = sx + d.speed * d.cos
    local real y = sy + d.speed * d.sin
    local integer mode = d.EffectMode
    if d.speed <= 0 then
        call d.destroy()
    endif
    if d.Trees == true then
        call SetRect(TreeRect,sx-RADIUS,sy-RADIUS,sx+RADIUS,sy+RADIUS)
        call EnumDestructablesInRect(TreeRect,TreeCheck,function Trees)
        endif
        if d.AllowMove == true then
        call SetUnitX(d.target,x)
        call SetUnitY(d.target,y)
        else
    call SetUnitPosition(u,x,y)
    endif
    set d.EffectMode = d.TerrainCheck(d)
    if d.EffectMode == 1 and (mode == 2 or mode == 3) then
        call DestroyEffect(d.effects)
        set d.effects = AddSpecialEffectTarget(GROUND,d.target,ATTACHPOINT)
    elseif d.EffectMode == 2 and (mode == 1 or mode == 3) then
        call DestroyEffect(d.effects)
        set d.effects = AddSpecialEffectTarget(WATER,d.target,ATTACHPOINT)
    elseif d.EffectMode == 3 and (mode == 1 or mode == 2) then
        call DestroyEffect(d.effects)
        set d.effects = AddSpecialEffectTarget(COLLISION,d.target,ATTACHPOINT)
    endif
        set d.speed = d.speed - d.decrement
    set u = null
endfunction

function KnockbackTarget takes unit source, unit target , real angle, real speed, real decrement,boolean KillTree,boolean AllowMove returns boolean
    local Knock d = 0
    if target == null or source == null or speed == null or decrement == null then
        call BJDebugMsg("Invalid Values!")
        return false
    endif
    set d = Knock.create(source,target,angle,speed,decrement,KillTree,AllowMove)
    call SetTimerData(d.Timer,d)
    call TimerStart(d.Timer,TIME,true,function Update)
    return true
endfunction


private function Init takes nothing returns nothing
    set TreeRect = Rect(0,0,1,1)
    set TreeCheck = Filter(function CheckTrees)
endfunction
endlibrary
 

Kenny

Back for now.
Reaction score
202
It is because IsTerrainWalkable uses items to detect pathability. They do not count units as being not pathable, its just how it works. If you want it to detect units too, you will have to group units around the sliding unit, then play the effect when a unit comes within like 100 range of the sliding unit.
 

wraithseeker

Tired.
Reaction score
122
JASS:
//Formula to calculate Distance = -1 * V * V / (2 * A / Interval)  Where variable V is speed and A is decrement.//
//                            Note! V must be positive and A must be negative!!!!                             //
library Knockback initializer Init requires BoundSentinel, DestructableLib, IsTerrainWalkable

globals
    private constant real TIME = 0.03
    private constant string GROUND = "MDX\\Dust.mdx"
    private constant string WATER = "MDX\\SlideWater.mdx"
    private constant string COLLISION = "MDX\\DustAndRocks.mdx"
    private constant string ATTACHPOINT = "origin"
    private constant real RADIUS = 180
    private timer Timer = CreateTimer()
    private integer Count = 0
    private integer array Knocker
    private rect TreeRect
    private boolexpr TreeCheck
endglobals

private function CheckTrees takes nothing returns boolean
    if IsDestructableTree(GetFilterDestructable()) then
        return true
    endif
    return false
endfunction

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

private struct Knock
    unit source
    unit target
    real x
    real y
    real cos
    real sin
    real speed
    real decrement
    effect effects
    boolean Terrain
    integer EffectMode
    boolean Trees
    boolean AllowMove
    
    public method TerrainCheck takes Knock d returns integer
        local real x = GetUnitX(d.target)
        local real y = GetUnitY(d.target)

        if IsTerrainWalkable(x + 50.00 * d.cos,y + 50.00 * d.sin) == false then
            return 3
        else
            if IsTerrainPathable(x,y,PATHING_TYPE_FLOATABILITY) then
                return 1
            elseif not IsTerrainPathable(x,y,PATHING_TYPE_WALKABILITY) then
                return 2
            endif
        endif 
        return 0
        endmethod

static method create takes unit source, unit target, real angle, real speed, real decrement, boolean KillTree, boolean Allowmove returns Knock
    local Knock d = Knock.allocate()
    local real x
    local real y
    set d.source = source
    set d.target = target
    set d.Trees = KillTree
    set d.AllowMove = Allowmove
    set x = GetUnitX(d.target)
    set y = GetUnitY(d.target)
    set d.speed = speed * TIME
    set d.decrement = decrement * TIME
    set d.sin = Sin(angle)
    set d.cos = Cos(angle)
    set d.EffectMode = d.TerrainCheck(d)
    if d.EffectMode == 1 then
        set d.effects = AddSpecialEffectTarget(GROUND,d.target,ATTACHPOINT)
    endif
    if d.EffectMode == 2 then
        set d.effects = AddSpecialEffectTarget(WATER,d.target,ATTACHPOINT)
    endif
    if d.EffectMode == 3 then
     set d.effects = AddSpecialEffectTarget(COLLISION,d.target,ATTACHPOINT)
    endif
    return d
    endmethod
    
method onDestroy takes nothing returns nothing
    call DestroyEffect(this.effects)
    endmethod
        endstruct

private function Update takes nothing returns nothing
    local Knock d = Knock(GetTimerData(GetExpiredTimer()))
    local unit u = d.target
    local real sx = GetUnitX(u)
    local real sy = GetUnitY(u)
    local real x = sx + d.speed * d.cos
    local real y = sy + d.speed * d.sin
    local integer i = Count - 1
    local integer mode = d.EffectMode
    loop
    exitwhen i < 0
    if d.speed <= 0 then
        call d.destroy()
        set Count = Count - 1
        if Count < 0 then
        call PauseTimer(Timer)
        set Count = 0
        else
        set Knocker<i> = Knocker[Count]
    endif
    else
        if d.AllowMove == true then
        call SetUnitX(d.target,x)
        call SetUnitY(d.target,y)
        else
    call SetUnitPosition(u,x,y)
    endif
     if d.Trees == true then
        call SetRect(TreeRect,sx-RADIUS,sy-RADIUS,sx+RADIUS,sy+RADIUS)
        call EnumDestructablesInRect(TreeRect,TreeCheck,function Trees)
        endif
    set d.EffectMode = d.TerrainCheck(d)
    if d.EffectMode == 1 and (mode == 2 or mode == 3) then
        call DestroyEffect(d.effects)
        set d.effects = AddSpecialEffectTarget(GROUND,d.target,ATTACHPOINT)
    elseif d.EffectMode == 2 and (mode == 1 or mode == 3) then
        call DestroyEffect(d.effects)
        set d.effects = AddSpecialEffectTarget(WATER,d.target,ATTACHPOINT)
    elseif d.EffectMode == 3 and (mode == 1 or mode == 2) then
        call DestroyEffect(d.effects)
        set d.effects = AddSpecialEffectTarget(COLLISION,d.target,ATTACHPOINT)
    endif
        set d.speed = d.speed - d.decrement
        set i = i - 1
        endif
        endloop
    set u = null
endfunction

function KnockbackTarget takes unit source, unit target , real angle, real speed, real decrement,boolean KillTree,boolean AllowMove returns boolean
    local Knock d = 0
    if target == null or source == null or speed == null or decrement == null then
        call BJDebugMsg(&quot;Invalid Values!&quot;)
        return false
    endif
    set d = Knock.create(source,target,angle,speed,decrement,KillTree,AllowMove)
    if Count == 0 then
    call TimerStart(Timer,TIME,true,function Update)
    endif
    set Knocker[Count] = d
    set Count = Count + 1
    return true
endfunction


private function Init takes nothing returns nothing
    set TreeRect = Rect(0,0,1,1)
    set TreeCheck = Filter(function CheckTrees)
endfunction
endlibrary</i>


Can anyone tell me what's wrong , there is only effect but no knockback now.
 

Viikuna

No Marlo no game.
Reaction score
265
Seriously. Learn to properly Debug your code. Add some debug msges and comments so it is easier for you to find bugs and us to help you.
 

wraithseeker

Tired.
Reaction score
122
The effects are only d.Effects which are varied from GROUND , WATER , COLLISION.

The knockback doesn't work meaning the unit still stand in place.


JASS:
if d.EffectMode == 1 and (mode == 2 or mode == 3) then
        call DestroyEffect(d.effects)
        set d.effects = AddSpecialEffectTarget(GROUND,d.target,ATTACHPOINT)
    elseif d.EffectMode == 2 and (mode == 1 or mode == 3) then
        call DestroyEffect(d.effects)
        set d.effects = AddSpecialEffectTarget(WATER,d.target,ATTACHPOINT)
    elseif d.EffectMode == 3 and (mode == 1 or mode == 2) then
        call DestroyEffect(d.effects)
        set d.effects = AddSpecialEffectTarget(COLLISION,d.target,ATTACHPOINT)
    endif


Which worked.
 

Kenny

Back for now.
Reaction score
202
JASS:
private function Update takes nothing returns nothing
    local Knock d = Knock(GetTimerData(GetExpiredTimer()))
    local unit u = d.target
    local real sx = GetUnitX(u)
    local real sy = GetUnitY(u)
    local real x = sx + d.speed * d.cos
    local real y = sy + d.speed * d.sin
    local integer i = Count - 1
    local integer mode = d.EffectMode


You still have to port all of that stuff to your struct array loop, because d.target and all that does not exist outside of the loop.
 

Viikuna

No Marlo no game.
Reaction score
265
JASS:
local Knock d = Knock(GetTimerData(GetExpiredTimer()))

What is this for?
You should set d=Knocker in your loop..

If you want to use a single timer aproach, you can always check my Timer Tutorial or some other single timer knockback system.
 

Kenny

Back for now.
Reaction score
202
JASS:
//Formula to calculate Distance = -1 * V * V / (2 * A / Interval)  Where variable V is speed and A is decrement.//
//                            Note! V must be positive and A must be negative!!!!                             //
library Knockback initializer Init requires BoundSentinel, DestructableLib, IsTerrainWalkable

private keyword Knock

globals
    private constant real TIME = 0.03
    private constant string GROUND = &quot;MDX\\Dust.mdx&quot;
    private constant string WATER = &quot;MDX\\SlideWater.mdx&quot;
    private constant string COLLISION = &quot;MDX\\DustAndRocks.mdx&quot;
    private constant string ATTACHPOINT = &quot;origin&quot;
    private constant real RADIUS = 180
    private timer Timer = CreateTimer()
    private integer Count = 0
    private Knock array Knocker
    private rect TreeRect
    private boolexpr TreeCheck
endglobals

private function CheckTrees takes nothing returns boolean
    if IsDestructableTree(GetFilterDestructable()) then
        return true
    endif
    return false
endfunction

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

private struct Knock
    unit source
    unit target
    real x
    real y
    real cos
    real sin
    real speed
    real decrement
    effect effects
    boolean Terrain
    integer EffectMode
    boolean Trees
    boolean AllowMove
    
    public method TerrainCheck takes Knock d returns integer
        local real x = GetUnitX(d.target)
        local real y = GetUnitY(d.target)

        if IsTerrainWalkable(x + 50.00 * d.cos,y + 50.00 * d.sin) == false then
            return 3
        else
            if IsTerrainPathable(x,y,PATHING_TYPE_FLOATABILITY) then
                return 1
            elseif not IsTerrainPathable(x,y,PATHING_TYPE_WALKABILITY) then
                return 2
            endif
        endif 
        
        return 0
    endmethod

    static method create takes unit source, unit target, real angle, real speed, real decrement, boolean KillTree, boolean Allowmove returns Knock
        local Knock d = Knock.allocate()
        local real x
        local real y
        
        set d.source = source
        set d.target = target
        set d.Trees = KillTree
        set d.AllowMove = Allowmove
        set x = GetUnitX(d.target)
        set y = GetUnitY(d.target)
        set d.speed = speed * TIME
        set d.decrement = decrement * TIME
        set d.sin = Sin(angle)
        set d.cos = Cos(angle)
        set d.EffectMode = d.TerrainCheck(d)
        
        if d.EffectMode == 1 then
            set d.effects = AddSpecialEffectTarget(GROUND,d.target,ATTACHPOINT)
        endif
        if d.EffectMode == 2 then
            set d.effects = AddSpecialEffectTarget(WATER,d.target,ATTACHPOINT)
        endif
        if d.EffectMode == 3 then
         set d.effects = AddSpecialEffectTarget(COLLISION,d.target,ATTACHPOINT)
        endif
        
        return d
    endmethod
    
    method onDestroy takes nothing returns nothing
        call DestroyEffect(this.effects)
    endmethod
    
endstruct

private function Update takes nothing returns nothing
    local Knock d = 0
    local integer mode = 0
    local integer i = Count - 1
    local real x = 0.00
    local real y = 0.00
    
    loop
        exitwhen i &lt; 0
        local Knock d = Knocker<i>
        set mode = d.EffectMode
        
        set x = GetUnitX(d.target)
        set y = GetUnitY(d.target)
        
        if d.speed &lt;= 0 then
            call d.destroy()
            set Knocker<i> = Knocker[Count]
            set Count = Count - 1
        else
            set x = x + d.speed * d.cos
            set y = y + d.speed * d.sin
            
            if d.AllowMove == true then
                call SetUnitX(d.target,x)
                call SetUnitY(d.target,y)
            else
                call SetUnitPosition(d.target,x,y)
            endif
            
            if d.Trees == true then
                call SetRect(TreeRect,sx-RADIUS,sy-RADIUS,sx+RADIUS,sy+RADIUS)
                call EnumDestructablesInRect(TreeRect,TreeCheck,function Trees)
            endif
            
            set d.EffectMode = d.TerrainCheck(d)
            
            if d.EffectMode == 1 and (mode == 2 or mode == 3) then
                call DestroyEffect(d.effects)
                set d.effects = AddSpecialEffectTarget(GROUND,d.target,ATTACHPOINT)
            elseif d.EffectMode == 2 and (mode == 1 or mode == 3) then
                call DestroyEffect(d.effects)
                set d.effects = AddSpecialEffectTarget(WATER,d.target,ATTACHPOINT)
            elseif d.EffectMode == 3 and (mode == 1 or mode == 2) then
                call DestroyEffect(d.effects)
                set d.effects = AddSpecialEffectTarget(COLLISION,d.target,ATTACHPOINT)
            endif
            
            set d.speed = d.speed - d.decrement
        endif
        
        set i = i - 1
    endloop
    
    if Count &lt;= 0 then
        call PauseTimer(Timer)
        set Count = 0
    endif
endfunction

function KnockbackTarget takes unit source, unit target , real angle, real speed, real decrement,boolean KillTree,boolean AllowMove returns boolean
    local Knock d = 0
    
    if target == null or source == null or speed == null or decrement == null then
        call BJDebugMsg(&quot;Invalid Values!&quot;)
        return false
    endif
    
    set d = Knock.create(source,target,angle,speed,decrement,KillTree,AllowMove)
    
    if Count == 0 then
        call TimerStart(Timer,TIME,true,function Update)
    endif
    
    set Knocker[Count] = d
    set Count = Count + 1
    
    return true
endfunction

private function Init takes nothing returns nothing
    set TreeRect = Rect(0,0,1,1)
    set TreeCheck = Filter(function CheckTrees)
endfunction

endlibrary
</i></i>


I think thats a bit closer to what you want.
 
General chit-chat
Help Users
  • No one is chatting at the moment.
  • Ghan Ghan:
    Howdy
  • Ghan Ghan:
    Still lurking
    +3
  • The Helper The Helper:
    I am great and it is fantastic to see you my friend!
    +1
  • The Helper The Helper:
    If you are new to the site please check out the Recipe and Food Forum https://www.thehelper.net/forums/recipes-and-food.220/
  • Monovertex Monovertex:
    How come you're so into recipes lately? Never saw this much interest in this topic in the old days of TH.net
  • Monovertex Monovertex:
    Hmm, how do I change my signature?
  • tom_mai78101 tom_mai78101:
    Signatures can be edit in your account profile. As for the old stuffs, I'm thinking it's because Blizzard is now under Microsoft, and because of Microsoft Xbox going the way it is, it's dreadful.
  • The Helper The Helper:
    I am not big on the recipes I am just promoting them - I use the site as a practice place promoting stuff
    +2
  • Monovertex Monovertex:
    @tom_mai78101 I must be blind. If I go on my profile I don't see any area to edit the signature; If I go to account details (settings) I don't see any signature area either.
  • The Helper The Helper:
    You can get there if you click the bell icon (alerts) and choose preferences from the bottom, signature will be in the menu on the left there https://www.thehelper.net/account/preferences
  • The Helper The Helper:
    I think I need to split the Sci/Tech news forum into 2 one for Science and one for Tech but I am hating all the moving of posts I would have to do
  • The Helper The Helper:
    What is up Old Mountain Shadow?
  • The Helper The Helper:
    Happy Thursday!
    +1
  • Varine Varine:
    Crazy how much 3d printing has come in the last few years. Sad that it's not as easily modifiable though
  • Varine Varine:
    I bought an Ender 3 during the pandemic and tinkered with it all the time. Just bought a Sovol, not as easy. I'm trying to make it use a different nozzle because I have a fuck ton of Volcanos, and they use what is basically a modified volcano that is just a smidge longer, and almost every part on this thing needs to be redone to make it work
  • Varine Varine:
    Luckily I have a 3d printer for that, I guess. But it's ridiculous. The regular volcanos are 21mm, these Sovol versions are about 23.5mm
  • Varine Varine:
    So, 2.5mm longer. But the thing that measures the bed is about 1.5mm above the nozzle, so if I swap it with a volcano then I'm 1mm behind it. So cool, new bracket to swap that, but THEN the fan shroud to direct air at the part is ALSO going to be .5mm to low, and so I need to redo that, but by doing that it is a little bit off where it should be blowing and it's throwing it at the heating block instead of the part, and fuck man
  • Varine Varine:
    I didn't realize they designed this entire thing to NOT be modded. I would have just got a fucking Bambu if I knew that, the whole point was I could fuck with this. And no one else makes shit for Sovol so I have to go through them, and they have... interesting pricing models. So I have a new extruder altogether that I'm taking apart and going to just design a whole new one to use my nozzles. Dumb design.
  • Varine Varine:
    Can't just buy a new heatblock, you need to get a whole hotend - so block, heater cartridge, thermistor, heatbreak, and nozzle. And they put this fucking paste in there so I can't take the thermistor or cartridge out with any ease, that's 30 dollars. Or you can get the whole extrudor with the direct driver AND that heatblock for like 50, but you still can't get any of it to come apart
  • Varine Varine:
    Partsbuilt has individual parts I found but they're expensive. I think I can get bits swapped around and make this work with generic shit though
  • Ghan Ghan:
    Heard Houston got hit pretty bad by storms last night. Hope all is well with TH.
  • The Helper The Helper:
    Power back on finally - all is good here no damage
    +2
  • V-SNES V-SNES:
    Happy Friday!
    +1

      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