• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

Easy JASS question concerning knockback

Status
Not open for further replies.
Level 5
Joined
Feb 27, 2009
Messages
115
Hi all! I need to slightly alter a knockback trigger so it does not knockback buildings! (so odd when buildings get bounced back. Really ruins the spells). So what I am intending to do is to figure out where to boolarean of 'Is unit building, then leave alone'.

Usually whenever I mess with other people's triggers/spells, I get bad results. So perhaps someone might assist me in figuring out where to insert the boolarean so the knockback no longer bounces buildings on the map.

Here is the trigger:

JASS:
library Knockback initializer Init

    globals
        private constant integer FPS = 40 // Higher than 40 may cause lags. Because 40 fps is 0.025 interval and 60 is 0.01.

        private constant integer EffectRandom = 4 // 4 is 25% chance of the effect spawning( Looping effect )

        private integer array Index
        private integer Total = 0
        private timer Tim = CreateTimer()

        private real MAX_X
        private real MAX_Y
        private real MIN_X
        private real MIN_Y

        private boolexpr FilterDestructables

        private real Interval
    endglobals

    private function DestructableFilter takes nothing returns boolean
        local destructable d = GetFilterDestructable()
        if GetWidgetLife(d) > .405 and not IsDestructableInvulnerable(d) then
            call KillDestructable(d)
        endif
        set d = null
        return false
    endfunction

    private keyword Data // If not here then the loop cannot be put over the struct( Why is because the struct needs the function for the timer )

    private function Loop takes nothing returns nothing
        local Data dat
        local integer i=0

        loop
            exitwhen i >= Total
            set dat = Index[i]

            if dat.v <= 0 then
                if dat.s != "" and dat.s != null then
                    if dat.e != null then
                        call DestroyEffect(dat.e)
                        set dat.e = null
                    endif
                    set dat.s = null
                elseif dat.e != null then
                    call DestroyEffect(dat.e)
                    set dat.e = null
                endif

                if dat.p then
                    call PauseUnit(dat.u, false)
                    set dat.p = false
                endif

                call SetUnitPosition(dat.u, GetUnitX(dat.u), GetUnitY(dat.u))
                
                set dat.u = null

                call dat.destroy()

                set Total = Total - 1
                set Index[i] = Index[Total]

                set i = i - 1
            else
                set dat.nX = GetUnitX(dat.u) + dat.v * dat.cos
                set dat.nY = GetUnitY(dat.u) + dat.v * dat.sin

                if dat.nX < MAX_X and dat.nY < MAX_Y and dat.nX > MIN_X and dat.nY > MIN_Y and GetWidgetLife(dat.u) > .405 then
                    call SetUnitX(dat.u, dat.nX)
                    call SetUnitY(dat.u, dat.nY)

                    if dat.r > 0 then // If the member ' r ' is greater than 0 it will destroy destructables in a desired range
                        set dat.R = Rect(dat.nX - dat.r, dat.nY - dat.r, dat.nX + dat.r, dat.nY + dat.r)
                        call EnumDestructablesInRect(dat.R, FilterDestructables, null)
                    endif

                    if dat.s != "" and dat.s != null then
                        if dat.er == 0 then
                            if GetRandomInt(1, EffectRandom) == EffectRandom then // Here is where the global random integer is used
                                call DestroyEffect(AddSpecialEffect(dat.s, dat.nX, dat.nY))
                            endif
                        elseif dat.i >= dat.er then
                            call DestroyEffect(AddSpecialEffect(dat.s, dat.nX, dat.nY))
                            set dat.i = 0
                        else
                            set dat.i = dat.i + Interval
                        endif
                    endif

                    set dat.v = dat.v - dat.vd
                else
                    set dat.v = 0
                endif
            endif

            set i = i + 1
        endloop

        if Total == 0 then
            call PauseTimer(Tim)
        endif
    endfunction

    private struct Data
        unit u

        real v = 0
        real vd

        real cos
        real sin

        real r = 0

        string s
        effect e

        real i = 0
        real er = 0

        boolean p

        static real nX
        static real nY
        static rect R = Rect(0,0,0,0)

        static method Start takes unit u, real d, real a, integer t, real r, boolean p, real er, integer i, string s, string s2 returns nothing
            local Data dat = Data.allocate()

            set dat.u = u
            set dat.er = er

            set dat.v = 2*d / (t + 1)
            set dat.vd = dat.v / t

            set dat.cos = Cos(a)
            set dat.sin = Sin(a)

            if s != "" and s != null then
                if i == 1 then
                    set dat.s = s
                elseif i == 2 then
                    set dat.e = AddSpecialEffectTarget(s, u, s2)
                elseif i == 3 then
                    set dat.s = s
                    set dat.e = AddSpecialEffectTarget(s, u, s2)
                endif
            endif

            if p then
                call PauseUnit(u, true)
                set dat.p = p
            endif

            if r > 0 then
                set dat.r = r
            endif

            if Total == 0 then
                call TimerStart(Tim, Interval, true, function Loop)
            endif

            set Index[Total] = dat
            set Total = Total + 1
        endmethod
    endstruct

    function KnockbackEx takes unit Unit, real Distance, real RadAngle, real Time, real Radius, boolean Pause, real EffectSpawn, integer EffectInt, string Effect, string EffectAttach returns nothing
        call Data.Start(Unit, Distance, RadAngle, R2I(Time / Interval), Radius, Pause, EffectSpawn, EffectInt, Effect, EffectAttach)
    endfunction

    function Knockback takes unit Unit, real Distance, real RadAngle, real Time, boolean Pause returns nothing
        call Data.Start(Unit, Distance, RadAngle, R2I(Time / Interval), 0, Pause, 0, 0, "", "")
    endfunction

    private function Init takes nothing returns nothing
        set MAX_X = GetRectMaxX(bj_mapInitialPlayableArea)
        set MAX_Y = GetRectMaxY(bj_mapInitialPlayableArea)
        set MIN_X = GetRectMinX(bj_mapInitialPlayableArea)
        set MIN_Y = GetRectMinY(bj_mapInitialPlayableArea)

        set FilterDestructables = Condition(function DestructableFilter)

        set Interval = (1.0 / FPS)
    endfunction
endlibrary
 
Last edited by a moderator:
Level 18
Joined
Jan 21, 2006
Messages
2,552
When I see stuff like this it makes me want to close my internet browser and dip-set. For Christ's sake man.

JASS:
library Knockback initializer Init

globals
    private constant integer FPS = 40 // Higher than 40 may cause lags. Because 40 fps is 0.025 interval and 60 is 0.01.

    private constant integer EffectRandom = 4 // 4 is 25% chance of the effect spawning( Looping effect )

    private integer array Index
    private integer Total = 0
    private timer Tim = CreateTimer()

    private real MAX_X
    private real MAX_Y
    private real MIN_X
    private real MIN_Y

    private boolexpr FilterDestructables

    private real Interval
endglobals

private function DestructableFilter takes nothing returns boolean
    local destructable d = GetFilterDestructable()
    if GetWidgetLife(d) > .405 and not IsDestructableInvulnerable(d) then
        call KillDestructable(d)
    endif
    set d = null
    return false
endfunction

private keyword Data // If not here then the loop cannot be put over the struct( Why is because the struct needs the function for the timer )

private function Loop takes nothing returns nothing
    local Data dat
    local integer i=0

    loop
        exitwhen i >= Total
        set dat = Index[i]

        if dat.v <= 0 then
            if dat.s != "" and dat.s != null then
                if dat.e != null then
                    call DestroyEffect(dat.e)
                    set dat.e = null
                endif
                set dat.s = null
            elseif dat.e != null then
                call DestroyEffect(dat.e)
                set dat.e = null
            endif

            if dat.p then
                call PauseUnit(dat.u, false)
                set dat.p = false
            endif

            call SetUnitPosition(dat.u, GetUnitX(dat.u), GetUnitY(dat.u))

            set dat.u = null

            call dat.destroy()

            set Total = Total - 1
            set Index[i] = Index[Total]

            set i = i - 1
            
        else
        
            set dat.nX = GetUnitX(dat.u) + dat.v * dat.cos
            set dat.nY = GetUnitY(dat.u) + dat.v * dat.sin

            if dat.nX < MAX_X and dat.nY < MAX_Y and dat.nX > MIN_X and dat.nY > MIN_Y and GetWidgetLife(dat.u) > .405 then
                call SetUnitX(dat.u, dat.nX)
                call SetUnitY(dat.u, dat.nY)

                if dat.r > 0 then // If the member ' r ' is greater than 0 it will destroy destructables in a desired range
                    set dat.R = Rect(dat.nX - dat.r, dat.nY - dat.r, dat.nX + dat.r, dat.nY + dat.r)
                    call EnumDestructablesInRect(dat.R, FilterDestructables, null)
                endif

                if dat.s != "" and dat.s != null then
                    if dat.er == 0 then
                        if GetRandomInt(1, EffectRandom) == EffectRandom then // Here is where the global random integer is used
                            call DestroyEffect(AddSpecialEffect(dat.s, dat.nX, dat.nY))
                        endif
                    elseif dat.i >= dat.er then
                        call DestroyEffect(AddSpecialEffect(dat.s, dat.nX, dat.nY))
                        set dat.i = 0
                    else
                        set dat.i = dat.i + Interval
                    endif
                endif

                set dat.v = dat.v - dat.vd
            else
                set dat.v = 0
            endif
            
        endif

        set i = i + 1
    endloop

    if Total == 0 then
        call PauseTimer(Tim)
    endif
endfunction

private struct Data
    unit u

    real v = 0
    real vd

    real cos
    real sin

    real r = 0

    string s
    effect e

    real i = 0
    real er = 0

    boolean p

    static real nX
    static real nY
    static rect R = Rect(0,0,0,0)

    static method Start takes unit u, real d, real a, integer t, real r, boolean p, real er, integer i, string s, string s2 returns nothing
        local Data dat = Data.allocate()

        set dat.u = u
        set dat.er = er

        set dat.v = 2*d / (t + 1)
        set dat.vd = dat.v / t

        set dat.cos = Cos(a)
        set dat.sin = Sin(a)

        if s != "" and s != null then
            if i == 1 then
                set dat.s = s
            elseif i == 2 then
                set dat.e = AddSpecialEffectTarget(s, u, s2)
            elseif i == 3 then
                set dat.s = s
                set dat.e = AddSpecialEffectTarget(s, u, s2)
            endif
        endif

        if p then
            call PauseUnit(u, true)
            set dat.p = p
        endif

        if r > 0 then
            set dat.r = r
        endif

        if Total == 0 then
            call TimerStart(Tim, Interval, true, function Loop)
        endif

        set Index[Total] = dat
        set Total = Total + 1
    endmethod
endstruct

function KnockbackEx takes unit Unit, real Distance, real RadAngle, real Time, real Radius, boolean Pause, real EffectSpawn, integer EffectInt, string Effect, string EffectAttach returns nothing
    call Data.Start(Unit, Distance, RadAngle, R2I(Time / Interval), Radius, Pause, EffectSpawn, EffectInt, Effect, EffectAttach)
endfunction

function Knockback takes unit Unit, real Distance, real RadAngle, real Time, boolean Pause returns nothing
    call Data.Start(Unit, Distance, RadAngle, R2I(Time / Interval), 0, Pause, 0, 0, "", "")
endfunction

private function Init takes nothing returns nothing
    set MAX_X = GetRectMaxX(bj_mapInitialPlayableArea)
    set MAX_Y = GetRectMaxY(bj_mapInitialPlayableArea)
    set MIN_X = GetRectMinX(bj_mapInitialPlayableArea)
    set MIN_Y = GetRectMinY(bj_mapInitialPlayableArea)

    set FilterDestructables = Condition(function DestructableFilter)

    set Interval = (1.0 / FPS)
endfunction
endlibrary

The lack of indentation made it impossible to read.
 
Level 9
Joined
Nov 28, 2008
Messages
704
Hi all! I need to slightly alter a knockback trigger so it does not knockback buildings! (so odd when buildings get bounced back. Really ruins the spells). So what I am intending to do is to figure out where to boolarean of 'Is unit building, then leave alone'.

Usually whenever I mess with other people's triggers/spells, I get bad results. So perhaps someone might assist me in figuring out where to insert the boolarean so the knockback no longer bounces buildings on the map.

Here is the trigger:
JASS:
library Knockback initializer Init

    globals
        private constant integer FPS = 40 // Higher than 40 may cause lags. Because 40 fps is 0.025 interval and 60 is 0.01.

        private constant integer EffectRandom = 4 // 4 is 25% chance of the effect spawning( Looping effect )

        private integer array Index
        private integer Total = 0
        private timer Tim = CreateTimer()

        private real MAX_X
        private real MAX_Y
        private real MIN_X
        private real MIN_Y

        private boolexpr FilterDestructables

        private real Interval
    endglobals

    private function DestructableFilter takes nothing returns boolean
        local destructable d = GetFilterDestructable()
        if GetWidgetLife(d) > .405 and not IsDestructableInvulnerable(d) then
            call KillDestructable(d)
        endif
        set d = null
        return false
    endfunction

    private keyword Data // If not here then the loop cannot be put over the struct( Why is because the struct needs the function for the timer )

    private function Loop takes nothing returns nothing
        local Data dat
        local integer i=0

        loop
            exitwhen i >= Total
            set dat = Index[i]

            if dat.v <= 0 then
                if dat.s != "" and dat.s != null then
                    if dat.e != null then
                        call DestroyEffect(dat.e)
                        set dat.e = null
                    endif
                    set dat.s = null
                elseif dat.e != null then
                    call DestroyEffect(dat.e)
                    set dat.e = null
                endif

                if dat.p then
                    call PauseUnit(dat.u, false)
                    set dat.p = false
                endif

                call SetUnitPosition(dat.u, GetUnitX(dat.u), GetUnitY(dat.u))
                
                set dat.u = null

                call dat.destroy()

                set Total = Total - 1
                set Index[i] = Index[Total]

                set i = i - 1
            else
                set dat.nX = GetUnitX(dat.u) + dat.v * dat.cos
                set dat.nY = GetUnitY(dat.u) + dat.v * dat.sin

                if dat.nX < MAX_X and dat.nY < MAX_Y and dat.nX > MIN_X and dat.nY > MIN_Y and GetWidgetLife(dat.u) > .405 then
                    call SetUnitX(dat.u, dat.nX)
                    call SetUnitY(dat.u, dat.nY)

                    if dat.r > 0 then // If the member ' r ' is greater than 0 it will destroy destructables in a desired range
                        set dat.R = Rect(dat.nX - dat.r, dat.nY - dat.r, dat.nX + dat.r, dat.nY + dat.r)
                        call EnumDestructablesInRect(dat.R, FilterDestructables, null)
                    endif

                    if dat.s != "" and dat.s != null then
                        if dat.er == 0 then
                            if GetRandomInt(1, EffectRandom) == EffectRandom then // Here is where the global random integer is used
                                call DestroyEffect(AddSpecialEffect(dat.s, dat.nX, dat.nY))
                            endif
                        elseif dat.i >= dat.er then
                            call DestroyEffect(AddSpecialEffect(dat.s, dat.nX, dat.nY))
                            set dat.i = 0
                        else
                            set dat.i = dat.i + Interval
                        endif
                    endif

                    set dat.v = dat.v - dat.vd
                else
                    set dat.v = 0
                endif
            endif

            set i = i + 1
        endloop

        if Total == 0 then
            call PauseTimer(Tim)
        endif
    endfunction

    private struct Data
        unit u

        real v = 0
        real vd

        real cos
        real sin

        real r = 0

        string s
        effect e

        real i = 0
        real er = 0

        boolean p

        static real nX
        static real nY
        static rect R = Rect(0,0,0,0)

        static method Start takes unit u, real d, real a, integer t, real r, boolean p, real er, integer i, string s, string s2 returns nothing
            local Data dat = Data.allocate()

            set dat.u = u
            set dat.er = er

            set dat.v = 2*d / (t + 1)
            set dat.vd = dat.v / t

            set dat.cos = Cos(a)
            set dat.sin = Sin(a)

            if s != "" and s != null then
                if i == 1 then
                    set dat.s = s
                elseif i == 2 then
                    set dat.e = AddSpecialEffectTarget(s, u, s2)
                elseif i == 3 then
                    set dat.s = s
                    set dat.e = AddSpecialEffectTarget(s, u, s2)
                endif
            endif

            if p then
                call PauseUnit(u, true)
                set dat.p = p
            endif

            if r > 0 then
                set dat.r = r
            endif

            if Total == 0 then
                call TimerStart(Tim, Interval, true, function Loop)
            endif

            set Index[Total] = dat
            set Total = Total + 1
        endmethod
    endstruct

    function KnockbackEx takes unit Unit, real Distance, real RadAngle, real Time, real Radius, boolean Pause, real EffectSpawn, integer EffectInt, string Effect, string EffectAttach returns nothing
        call Data.Start(Unit, Distance, RadAngle, R2I(Time / Interval), Radius, Pause, EffectSpawn, EffectInt, Effect, EffectAttach)
    endfunction

    function Knockback takes unit Unit, real Distance, real RadAngle, real Time, boolean Pause returns nothing
        call Data.Start(Unit, Distance, RadAngle, R2I(Time / Interval), 0, Pause, 0, 0, "", "")
    endfunction

    private function Init takes nothing returns nothing
        set MAX_X = GetRectMaxX(bj_mapInitialPlayableArea)
        set MAX_Y = GetRectMaxY(bj_mapInitialPlayableArea)
        set MIN_X = GetRectMinX(bj_mapInitialPlayableArea)
        set MIN_Y = GetRectMinY(bj_mapInitialPlayableArea)

        set FilterDestructables = Condition(function DestructableFilter)

        set Interval = (1.0 / FPS)
    endfunction
endlibrary

You know, its not the end of the world guys. Just push quote and do this (put it in boxes), then click preview post. >.>
 
Last edited by a moderator:
Status
Not open for further replies.
Top