• 🏆 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!

[JASS] - [vJASS] The Dash System. First time vJASSing. Help needed.

Status
Not open for further replies.
Level 12
Joined
Sep 24, 2007
Messages
283
Well i've read 2 toturials about JASS.
After that i tried to make the Dash system.
Well i got something like that:
System:
JASS:
library Dash

struct Dash_Data
    unit u
    real d1
    real d

    real sin
    real cos

    real r

    string s = ""
    effect e = null
endstruct

globals
    timer Tim = CreateTimer()
Dash_Data array Ar
    integer Total = 0

    item I = CreateItem('ciri', 0, 0)

    boolexpr Filter
endglobals

function CheckPathabilityTrickGet takes nothing returns nothing
    set bj_rescueChangeColorUnit = bj_rescueChangeColorUnit or GetEnumItem() != I
endfunction

function CheckPathabilityTrick takes real x, real y returns boolean
    local integer i = 30
    local real X
    local real Y
    local rect r
    call SetItemPosition(I, x, y)
    set X = GetItemX(I) - x
set Y = GetItemY(I) - y
    if X * X + Y * Y <= 100 then
        return true
    endif
    set r = Rect(x - i, y - i, x + i, y + i)
    set bj_rescueChangeColorUnit = false
call EnumItemsInRect(r, null, function CheckPathabilityTrickGet)
    call RemoveRect(r)
    set r = null
    return bj_rescueChangeColorUnit
endfunction

function CheckPathability takes real x, real y returns boolean
    local boolean b = CheckPathabilityTrick(x, y)
    call SetItemVisible(I, false)
return b
endfunction

function Dash_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

constant function Interval takes nothing returns real
    return 0.04
endfunction

function Dash_Execute takes nothing returns nothing
    local Dash_Data kd
    local integer i = 0
    local real x
    local real y
    local rect r
    local boolexpr b

    loop
        exitwhen i >= Total
        set kd = Ar[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
            set kd.d = kd.d - kd.d1
        else
            set x = GetUnitX(kd.u) + kd.d1 * kd.cos
            set y = GetUnitY(kd.u) + kd.d1 * kd.sin
        endif

        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 CheckPathability(x, y) then
            call SetUnitX(kd.u, x)
            call SetUnitY(kd.u, y)
        endif


        if kd.d <= 0 or not CheckPathability(x, y) then
            if kd.e != null then
                call DestroyEffect(kd.e)
            endif
            call PauseUnit(kd.u, false)
            set Ar[i] = Ar[Total - 1]
            set Total = Total - 1
            call kd.destroy()
        endif

        set i = i + 1
    endloop

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

function Dash takes unit u, real d, real a, real r, integer t, string s, string p returns Dash_Data
    local Dash_Data kd = Dash_Data.create()

    set kd.u = u
    set kd.a = a
    set kd.d1 = 20
    set kd.sin = Sin(a)
    set kd.cos = Cos(a)
    set kb.d = d

    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)

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

    set Total = Total + 1
    set Ar[Total - 1] = kd

    return kd
endfunction

endlibrary

Spell:
JASS:
function Trig_Dash_Spell_Conditions takes nothing returns boolean
		return GetSpellAbilityId() == 'A000'
endfunction

function Trig_Dash_Spell_Actions takes nothing returns nothing
local unit u = GetTriggerUnit()
local real d = 1000
local location array loc
local real a
local integer t = 1
local string s = "Abilities\\Weapons\\PhoenixMissile\\Phoenix_Missile.mdl"
local string p =""
local real r = 0

set loc[1] = GetUnitLoc(u)
set loc[2] = GetSpellTargetLoc()

set a = bj_RADTODEG * Atan2(GetLocationY(loc[2]) - GetLocationY(loc[1]), GetLocationX(loc[2]) - GetLocationX(loc[1]))
call Dash(u,d,a,r,t,s,p)

call RemoveLocation(loc[1])
call RemoveLocation(loc[1])
endfunction

//===========================================================================
function InitTrig_Dash_Spell takes nothing returns nothing
    local trigger Dash_Spell = CreateTrigger(  )
    local integer index

    set index = 0
    loop
        call TriggerRegisterPlayerUnitEvent(Dash_Spell, Player(index), EVENT_PLAYER_UNIT_SPELL_EFFECT, null)

        set index = index + 1
        exitwhen index == bj_MAX_PLAYER_SLOTS
    endloop

    call TriggerAddCondition(Dash_Spell, Condition( function Trig_Dash_Spell_Conditions ) )
    call TriggerAddAction(Dash_Spell, function Trig_Dash_Spell_Actions )
endfunction

Something is wrong here. Idk what >.<
 

Attachments

  • Dash - vJASS.w3x
    20.7 KB · Views: 51
Don't be so impatient... I'm looking over it now.

What I first notice is the lack of the "private" keyword. If a function or global variable should only be accessible from within your system, use the "private" keyword to avoid naming conflicts.

EDIT:
e.g.
JASS:
library MyLib
    globals
        private integer MyVar
    endglobals
    private function MyFunc takes nothing returns nothing
        //blah
    endfunction
endlibrary
The variable MyVar and function MyFunc will not be accessible from outside the library.

EDIT: You have a syntax error on this line call DestroyEffect(AddSpecialEffect(kd.s, x, y) You forgot to close the parentheses (")")
EDIT: You reference a struct member you haven't declared here set kd.a = a. Looking through the code it doesn't seem to be used for anything in the loop either, it's just for determining the sin/cos from the start.
EDIT: Another syntax error here set kb.d = d. You made a typo, it should be "kd"
EDIT: You may not call a global variable "Filter" since the name is already used by a native function. You also don't seem to initialise that variable anywhere.

EDIT: Ok, I fixed all the syntax errors and everything, and it still doesn't work. The *main* problem (there may be others I haven't found yet) is that the check pathability function returns false due to the actual unit which is moving being in the way. The code free of syntax errors and fixed up is the following. See if you can fix the pathability problem yourself...

JASS:
library Dash initializer Init
    private keyword Data
    
    globals
        private constant real TIMER_INTERVAL = 0.04
        
        private timer Tim = CreateTimer()
        private Data array Ar
        private integer Total = 0

        private item PathItem = CreateItem('ciri', 0, 0)
        private boolean TempBool

        private boolexpr filter
        private rect TempRect = Rect(0., 0., 0., 0.)
    endglobals

    private struct Data
        unit u
        real d1
        real d

        real sin
        real cos

        real r

        string s = ""
        effect e = null
    endstruct

    private function CheckPathabilityTrickGet takes nothing returns nothing
        set TempBool = TempBool or GetEnumItem() != PathItem
    endfunction

    private function CheckPathabilityTrick takes real x, real y returns boolean
        local integer i = 30
        local real X
        local real Y
        call SetItemPosition(PathItem, x, y)
        set X = GetItemX(PathItem) - x
        set Y = GetItemY(PathItem) - y
        if X * X + Y * Y <= 100 then
            return true
        endif
        call SetRect(TempRect, x - i, y - i, x + i, y + i)
        set TempBool = false
        call EnumItemsInRect(TempRect, null, function CheckPathabilityTrickGet)
        return TempBool
    endfunction

    private function CheckPathability takes real x, real y returns boolean
        local boolean b
        call SetItemVisible(PathItem, true)
        set b = CheckPathabilityTrick(x, y)
        call SetItemVisible(PathItem, false)
        return b
    endfunction

    private function 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

    private function Execute takes nothing returns nothing
        local Data kd
        local integer i = 0
        local real x
        local real y
        local rect r
        local boolean b

        loop
            exitwhen i >= Total
            set kd = Ar[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
                set kd.d = kd.d - kd.d1
            else
                set x = GetUnitX(kd.u) + kd.d1 * kd.cos
                set y = GetUnitY(kd.u) + kd.d1 * kd.sin
            endif

            if kd.r != 0 then
                call SetRect(TempRect, x - kd.r, y - kd.r, x + kd.r, y + kd.r)
                //call EnumDestructablesInRect(r, filter, function Knockback_KillTree)
            endif

            set b = CheckPathability(x, y)
            
            if b then
                call SetUnitX(kd.u, x)
                call SetUnitY(kd.u, y)
            endif

            if b == false then
                call BJDebugMsg("FALSE")
            endif

            if kd.d <= 0 or not b then
                if kd.e != null then
                    call DestroyEffect(kd.e)
                endif
                call PauseUnit(kd.u, false)
                set Ar[i] = Ar[Total - 1]
                set Total = Total - 1
                call kd.destroy()
                
                call BJDebugMsg("Dash end")
            endif
            
            set i = i + 1
        endloop

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

    function Dash takes unit u, real d, real a, real r, integer t, string s, string p returns Data
        local Data kd = Data.create()

        set kd.u = u
        set kd.d1 = 20
        set kd.sin = Sin(a)
        set kd.cos = Cos(a)
        set kd.d = d

        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)

        if Total == 0 then
            call TimerStart(Tim, TIMER_INTERVAL, true, function Execute)
        endif

        set Total = Total + 1
        set Ar[Total - 1] = kd

        return kd
    endfunction

    private function Init takes nothing returns nothing
        set filter = Filter(function TreeFilter)
    endfunction
    
endlibrary
JASS:
scope DashSpell initializer Init
    globals
        private constant real    DISTANCE   = 1000.
        private constant string  SFX1       = "Abilities\\Weapons\\PhoenixMissile\\Phoenix_Missile.mdl"
        private constant string  SFX2       = ""
        private constant integer SFX_TARGET = 1
        private constant real    RADIUS     = 0.
    endglobals
    
    private function Conditions takes nothing returns boolean
        return GetSpellAbilityId() == 'A000'
    endfunction

    private function Actions takes nothing returns nothing
        local unit u = GetTriggerUnit()
        call Dash(u, DISTANCE, bj_RADTODEG * Atan2(GetSpellTargetX() - GetUnitY(u), GetSpellTargetY() - GetUnitX(u)), RADIUS, SFX_TARGET, SFX1, SFX2)
    endfunction

    //===========================================================================
    private function Init takes nothing returns nothing
        local trigger t = CreateTrigger(  )
        local integer i = 0
        loop
            exitwhen i >= bj_MAX_PLAYER_SLOTS
            call TriggerRegisterPlayerUnitEvent(t, Player(i), EVENT_PLAYER_UNIT_SPELL_EFFECT, null)
            set i = i + 1
        endloop
        call TriggerAddCondition(t, Condition( function Conditions ) )
        call TriggerAddAction(t, function Actions)
    endfunction
endscope
Just ask again if you can't think of a way to fix it.
 
Last edited:
Level 16
Joined
Oct 12, 2008
Messages
1,570
JASS:
            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
                set kd.d = kd.d - kd.d1
            else
                set x = GetUnitX(kd.u) + kd.d1 * kd.cos
                set y = GetUnitY(kd.u) + kd.d1 * kd.sin
                // set kd.d = kd.d - kd.d1   <--- THAT
            endif
under the else action, you dont lower kd.d by kd.d1. under the If, you do.
And you compare kd.s to null twice. Compare to "" and null, as you do in the other parts
EoW seems to have fixed the rest.

BTW: Nidhogg, get used to coordinates, they dont leak and are used way more. Also, there are 2 natives now that remove the use of GetSpellTargetLoc(); GetSpellTargetX() and GetSpellTargetY()
 
Status
Not open for further replies.
Top