1. Updated Resource Submission Rules: All model & skin resource submissions must now include an in-game screenshot. This is to help speed up the moderation process and to show how the model and/or texture looks like from the in-game camera.
    Dismiss Notice
  2. DID YOU KNOW - That you can unlock new rank icons by posting on the forums or winning contests? Click here to customize your rank or read our User Rank Policy to see a list of ranks that you can unlock. Have you won a contest and still havn't received your rank award? Then please contact the administration.
    Dismiss Notice
  3. The Lich King demands your service! We've reached the 19th edition of the Icon Contest. Come along and make some chilling servants for the one true king.
    Dismiss Notice
  4. The 4th SFX Contest has started. Be sure to participate and have a fun factor in it.
    Dismiss Notice
  5. The poll for the 21st Terraining Contest is LIVE. Be sure to check out the entries and vote for one.
    Dismiss Notice
  6. The results are out! Check them out.
    Dismiss Notice
  7. Don’t forget to sign up for the Hive Cup. There’s a 555 EUR prize pool. Sign up now!
    Dismiss Notice
  8. The Hive Workshop Cup contest results have been announced! See the maps that'll be featured in the Hive Workshop Cup tournament!
    Dismiss Notice
  9. Check out the Staff job openings thread.
    Dismiss Notice
Dismiss Notice
60,000 passwords have been reset on July 8, 2019. If you cannot login, read this.

[JASS] Expected ' Error Help Please

Discussion in 'Triggers & Scripts' started by Darkwing, Aug 28, 2011.

  1. Darkwing

    Darkwing

    Joined:
    May 15, 2008
    Messages:
    150
    Resources:
    1
    Maps:
    1
    Resources:
    1
    Ok I've uber-mastered GUI(see my arena game) and am sick of it's limitations, and now I'm practicing Jass, but I still lack the experience. :eekani:

    What's the thing with the Expected ' :goblin_jawdrop: error I don't get that??
    Here is the code it shows that the error in this line:

    :fp:
    Code (vJASS):
        call TimerStart(T, 0.03, true, function  Blood_Twister_Execute())


    Uhm don't pay attention on the uncompletion (since it does nothing, 'xcept moving the dummy unit) of the spell I'm just practicing so I get the hang of using the timers.

    Thanx in advance!!! :thumbs_up:

    :fp:
    Code
    Code (vJASS):
    //Condition Main

    function Blood_Twister_Condition takes nothing returns boolean
        if ( not ( GetSpellAbilityId() == 'A004' ) ) then
            return false
        endif
        return true
    endfunction

    //Actionez

    function Blood_Twister_Execute takes nothing returns nothing
        local timer T = GetExpiredTimer()
        local unit sfx = LoadUnitHandle(udg_Hashtable, GetHandleId(GetTriggerUnit()), 2)
        local integer x = LoadIntegerBJ(1, GetHandleId(GetTriggerUnit()), udg_Hashtable)
        set x = x+1
        call SaveIntegerBJ(x, 1, GetHandleId(GetTriggerUnit()), udg_Hashtable)
        if x > 12 then
            call DisplayTextToForce( GetPlayersAll(), I2S(x) )
            call SetUnitPosition(sfx, PolarProjectionX( GetUnitX(sfx), 90, 0), PolarProjectionY( GetUnitY(sfx), 90, 0))
        else
            call PauseTimerBJ( true, T )
            call DestroyTimer(T)
            call KillUnit(sfx)
        endif
        set T = null
        set sfx = null
        call FlushChildHashtableBJ( GetHandleIdBJ(GetTriggerUnit()), udg_Hashtable )
    endfunction


    function Blood_Twister_Action takes nothing returns nothing
        local timer T = CreateTimer()
        local unit sfx
        local integer x = 0
        local real Angle = 0
        call CreateNUnitsAtLoc( 1, 'h000', GetOwningPlayer(GetTriggerUnit()), GetUnitLoc(GetTriggerUnit()), Angle )
        set sfx = GetLastCreatedUnit()
        call SetUnitAnimation(sfx, "birth")
        call QueueUnitAnimation(sfx, "stand")
        call SaveIntegerBJ(x, 1, GetHandleId(GetTriggerUnit()), udg_Hashtable)
        call SaveUnitHandleBJ(sfx, 2, GetHandleId(GetTriggerUnit()), udg_Hashtable)
        call TimerStart(T, 0.03, true, function  Blood_Twister_Execute())
        set T = null
        set sfx = null
    endfunction

    //////////////////////////////////////////////////////
    function InitTrig_Blood_Twister takes nothing returns nothing
        local trigger T = CreateTrigger(  )
        call TriggerRegisterAnyUnitEventBJ( T, EVENT_PLAYER_UNIT_SPELL_EFFECT )
        call TriggerAddCondition( T, Condition( function Blood_Twister_Condition ) )
        call TriggerAddAction( T, function Blood_Twister_Action )
        set T = null
    endfunction
     
  2. mckill2009

    mckill2009

    Joined:
    Mar 10, 2009
    Messages:
    4,696
    Resources:
    34
    Maps:
    5
    Spells:
    27
    JASS:
    2
    Resources:
    34
    this >>> Blood_Twister_Execute() >>> remove this >>> ()

    do NOT use BJ's, except for some few...

    samples;
    PauseTimerBJ >>> PauseUnit
    SaveIntegerBJ >>> SaveInteger
    and so on...

    also...this...
    Code (vJASS):

    function Blood_Twister_Condition takes nothing returns boolean
        if ( not ( GetSpellAbilityId() == 'A004' ) ) then
            return false
        endif
        return true
    endfunction
     


    to this...
    Code (vJASS):

    function Blood_Twister_Condition takes nothing returns boolean
       return GetSpellAbilityId() == 'A004'
    endfunction
     


    Welcome to the world of jazzers!
     
  3. Bannar

    Bannar

    Joined:
    Mar 19, 2008
    Messages:
    3,087
    Resources:
    20
    Spells:
    5
    Tutorials:
    1
    JASS:
    14
    Resources:
    20
    ^As mentioned, they are only few BJ (smaple, switch - generally 'red' functions) that are usefull, like:
    TriggerRegisterAnyUnitEventBJ
    and
    GetCurrentCameraSetup
    .

    JassCraft will help you a lot with replacing those into native, plus it hold wisdom about most Jass functions.

    - Conditions and Actions can be merged
    - Refer to timer's id instead of units one
    - Your 'Blood_Twister_Execute' function wouldn't work properly because GetTriggerUnit() will return null
    - use low letters for locals
    - bj_lastCreatedUnit can help you get rid of unneded local
    - flush child only when instance is finished
    - passing code callback funcion in TimerStart should be done without '()'
    - 'Angle' and 'x' variables aren't needed
    - use GetTriggerPlayer() instead of GetOwningPlayer()

    Fixed script
    Code (vJASS):

    function Blood_Twister_Execute takes nothing returns nothing
        local timer t = GetExpiredTimer()
        local integer id = GetHandleId(t)
        local integer x = LoadInteger(udg_Hashtable, id, 1) + 1
        local unit u = LoadUnitHandle(udg_Hashtable, id, 2)
        local real dx = GetUnitX(u) + 90 * Cos(0 * bj_DEGTORAD)
        local real dy = GetUnitY(u) + 90 * Sin(0 * bj_DEGTORAD)

        if x > 12 then
            if IsPlayerInForce(GetLocalPlayer(), bj_FORCE_ALL_PLAYERS) then
                call DisplayTextToPlayer(GetLocalPlayer(), 0, 0, I2S(x))
            endif
            call SetUnitPosition(u, dx, dy)
            call SaveInteger(udg_Hashtable, id, x)
        else
            call PauseTimer(t)
            call DestroyTimer(t)
            call KillUnit(u)
            call FlushChildHashtable(udg_Hashtable, id)
        endif

        set t = null
        set u = null
    endfunction

    function Blood_Twister_Condition takes nothing returns boolean
        local unit u = GetTriggerUnit()
        local timer t
        local integer id

        if GetSpellAbilityId() == 'A004' then
            set t = CreateTimer()
            set id = GetHandleId(t)
            set bj_lastCreatedUnit = CreateUnit(GetTriggerPlayer(), 'h000', GetUnitX(u), GetUnitY(u), bj_UNIT_FACING)
            call SetUnitAnimation(bj_lastCreatedUnit, "birth")
            call QueueUnitAnimation(bj_lastCreatedUnit, "stand")
            call SaveInteger(udg_Hashtable, id, 1, 0)
            call SaveUnitHandle(udg_Hashtable, id, 2, bj_lastCreatedUnit)
            call TimerStart(t, 0.03125, true, function  Blood_Twister_Execute)
            set t = null
        endif

        set u = null
        return false
    endfunction

    function InitTrig_Blood_Twister takes nothing returns nothing
        local trigger t = CreateTrigger(  )
        call TriggerRegisterAnyUnitEventBJ( t, EVENT_PLAYER_UNIT_SPELL_EFFECT )
        call TriggerAddCondition(t, Condition( function Blood_Twister_Condition ) )
        set t = null
    endfunction
     
     
    Last edited: Aug 28, 2011
  4. watermelon_1234

    watermelon_1234

    Joined:
    Nov 18, 2007
    Messages:
    1,066
    Resources:
    10
    Spells:
    9
    JASS:
    1
    Resources:
    10
    I would do things a bit differently.
    Code (vJASS):

    function Blood_Twister_Condition takes nothing returns boolean
        local unit u
        local timer t
        local integer id

        if GetSpellAbilityId() == 'A004' then
            set u = GetTriggerUnit()
            set t = CreateTimer()
            set id = GetHandleId(t)
            set bj_lastCreatedUnit = CreateUnit(GetTriggerPlayer(), 'h000', GetUnitX(u), GetUnitY(u), bj_UNIT_FACING)
            call SetUnitAnimation(bj_lastCreatedUnit, "birth")
            call QueueUnitAnimation(bj_lastCreatedUnit, "stand")
            call SaveInteger(udg_Hashtable, id, 1, 0)
            call SaveUnitHandle(udg_Hashtable, id, 2, bj_lastCreatedUnit)
            call TimerStart(t, 0.03125, true, function  Blood_Twister_Execute)
            set t = null
            set u = null
        endif
       
        return false
    endfunction
     
    Last edited: Aug 28, 2011
  5. Bannar

    Bannar

    Joined:
    Mar 19, 2008
    Messages:
    3,087
    Resources:
    20
    Spells:
    5
    Tutorials:
    1
    JASS:
    14
    Resources:
    20
    ^ I did mistake with CreateTimer() -> trigger would leak timer each time casted abill isn't 'A004' ;P Fixed, thanks.
    Although setting 'u' can be done even immidiately - there shouldn't be much problem with it.
     
  6. Pharaoh_

    Pharaoh_

    Joined:
    Nov 6, 2008
    Messages:
    8,127
    Resources:
    11
    Icons:
    3
    Skins:
    1
    Spells:
    6
    Tutorials:
    1
    Resources:
    11
    You also forgot the equal sign in the following line:
    Code (vJASS):
    set bj_lastCreatedUnit(GetTriggerPlayer(), 'h000', GetUnitX(u), GetUnitY(u), bj_UNIT_FACING)


    :]
     
  7. watermelon_1234

    watermelon_1234

    Joined:
    Nov 18, 2007
    Messages:
    1,066
    Resources:
    10
    Spells:
    9
    JASS:
    1
    Resources:
    10
    And
    CreateUnit
    .
    I looked too fast. :p
     
  8. Bannar

    Bannar

    Joined:
    Mar 19, 2008
    Messages:
    3,087
    Resources:
    20
    Spells:
    5
    Tutorials:
    1
    JASS:
    14
    Resources:
    20
    Not a sign but '= CreateUnit' ;] Why watermelon didn't see it ;S
    Freshhand rules ;X

    EDIT: Watermelon faster about 15sec :S
    EDIT2: I see you edited script too xD
     
  9. Bribe

    Bribe

    Joined:
    Sep 26, 2009
    Messages:
    8,059
    Resources:
    25
    Maps:
    3
    Spells:
    10
    Tutorials:
    3
    JASS:
    9
    Resources:
    25
    Using a single timer and looping through all instances via a unit group
    is a lot more efficient than using a timer for each unit (like TimerUtils)
    for a period less than or equal to 0.05.

    Sometimes it's better to stick with the GUI method.
     
  10. Bannar

    Bannar

    Joined:
    Mar 19, 2008
    Messages:
    3,087
    Resources:
    20
    Spells:
    5
    Tutorials:
    1
    JASS:
    14
    Resources:
    20
    Thats true, but it would change his script even more drasticaly - and thats not what we wanted. Actually he has to analize many improvements anyways, I'd profer to let him read few tutorials before going further.
     
  11. Magtheridon96

    Magtheridon96

    Joined:
    Dec 12, 2008
    Messages:
    6,006
    Resources:
    26
    Maps:
    1
    Spells:
    8
    Tutorials:
    7
    JASS:
    10
    Resources:
    26
    @Spunky:
    GetCurrentCameraSetup


    I taught you that :D

    I would recommend inlining it when you have heavy and potentially laggy camera systems, but keeping it as is is ok :)
     
  12. Bannar

    Bannar

    Joined:
    Mar 19, 2008
    Messages:
    3,087
    Resources:
    20
    Spells:
    5
    Tutorials:
    1
    JASS:
    14
    Resources:
    20
    And Bribe taught me
    TriggerRegisterAnyUnitEventBJ 
    ;P
     
  13. Bribe

    Bribe

    Joined:
    Sep 26, 2009
    Messages:
    8,059
    Resources:
    25
    Maps:
    3
    Spells:
    10
    Tutorials:
    3
    JASS:
    9
    Resources:
    25
    Most of the math utilities are fine like
    ModuloInteger, RMinBJ, IMinBJ, RMaxBJ, IMaxBJ
    and a number of others.
     
  14. Magtheridon96

    Magtheridon96

    Joined:
    Dec 12, 2008
    Messages:
    6,006
    Resources:
    26
    Maps:
    1
    Spells:
    8
    Tutorials:
    7
    JASS:
    10
    Resources:
    26
    Does JassHelper inline BJs? o_O
     
  15. Bribe

    Bribe

    Joined:
    Sep 26, 2009
    Messages:
    8,059
    Resources:
    25
    Maps:
    3
    Spells:
    10
    Tutorials:
    3
    JASS:
    9
    Resources:
    25
    The optimizer inlines BJ's mostly.

    However those ones above I'd usually not want to inline because I'd rather call the
    BJ than increase the size of my map by inlining them.
     
  16. Darkwing

    Darkwing

    Joined:
    May 15, 2008
    Messages:
    150
    Resources:
    1
    Maps:
    1
    Resources:
    1
    WOW guys I've just asked one question and all of you posted something and spinnaker even fixed the script, THANX +REP to all of you.

    :fp: @Spinnaker Tnx for the script once more by paralleling it with my script I cane get where am I doing wrong. :thumbs_up: I am in fact using JassCraft, but was just the random trigger I'm trying to convert my GUI trigger patterns to the Jass but I lack the xp and syntax and those finesses with BJ and stuff which you get with practice. :thumbs_up: Also thanks for the list of the tips :thumbs_up:

    :fp: @mckill2009 Thanks for the warm welcome and the explanation of the error ^^ I know about NOT USING BJ (one of the top 10 rules Jass) I'm just new as I said and trying to get a hang of it. :grin:

    :fp: @Watermelon and Pharaoh tnx for fixing the script GJ :thumbs_up:

    :fp: @Bribe actually I was using that trick of a timer and a unit group, but than started to use Time - Every _ seconds of game instead of timers, just I have a lot patterns for wave and similar spells and knockback 'n' jump sys and was making a set of variables for each of the spell's (xcept the sys) so I'm not sure if it is wise to put, let's say just pending spells into one group with some number of general variables to reduce the num of total vars, but then I think wouldn't it be slow trigger when it starts to cycle through all spells.

    :fp: @Magtheridon tnx for the tips.

    //==============================
    OK I've got some questions also, I've read a pretty fair amount of tutorials and still don't get some stuff.

    What's the difference between these two types of creating the trigger?

    Script
    Code (vJASS):
    function InitTrig_Blood_Twister takes nothing returns nothing
        local trigger t = CreateTrigger(  )
        call TriggerRegisterAnyUnitEventBJ( t, EVENT_PLAYER_UNIT_SPELL_EFFECT )
        call TriggerAddCondition(t, Condition( function Blood_Twister_Condition ) )
        set t = null
    endfunction

    //and this type of creating a trigger, sry it's just a converted empty trig

    function InitTrig_Blood_Twister takes nothing returns nothing
        set gg_trg_Blood_Twister = CreateTrigger(  )
        call TriggerAddAction( gg_trg_Blood_Twister, function Trig_Blood_Twister_Actions )
    endfunction


    Also can I have more than one creaton of trigger function in a single script, or I need to use those CreateTrigger and TriggerExecute func ,I thinks it was a tutorial which Vexorian wrote (I'll check that out) but I didn't get all of it really?

    I have some more questions but I'm in a hurry right now, I'll ask later. :thumbs_up:

    Thanx again all of you :ogre_haosis:
     
  17. Bribe

    Bribe

    Joined:
    Sep 26, 2009
    Messages:
    8,059
    Resources:
    25
    Maps:
    3
    Spells:
    10
    Tutorials:
    3
    JASS:
    9
    Resources:
    25
    Cycling through all spells is faster than having a million timers expire
    for each spell instance.
     
  18. Magtheridon96

    Magtheridon96

    Joined:
    Dec 12, 2008
    Messages:
    6,006
    Resources:
    26
    Maps:
    1
    Spells:
    8
    Tutorials:
    7
    JASS:
    10
    Resources:
    26
    Creating a local trigger with the name "t" is much more readable than using that really long ugly variable name that depends on the name of the trigger :/
     
  19. Bribe

    Bribe

    Joined:
    Sep 26, 2009
    Messages:
    8,059
    Resources:
    25
    Maps:
    3
    Spells:
    10
    Tutorials:
    3
    JASS:
    9
    Resources:
    25
    Yeah the global variable is pretty useless unless you depend on
    GUI trigger execution of some kind.
     
  20. mckill2009

    mckill2009

    Joined:
    Mar 10, 2009
    Messages:
    4,696
    Resources:
    34
    Maps:
    5
    Spells:
    27
    JASS:
    2
    Resources:
    34
    the difference is mainly >>> top uses local trigger, down a global which is pretty ugly...

    you can do this...
    Code (vJASS):

    local trigger t = CreateTrigger()
    call TriggerRegisterAnyUnitEventBJ...
    call AddAction...
    blahhhh...

    set t = CreateTrigger()
    call TriggerRegisterAnyUnitEventBJ...
    call AddAction...
    blahhh...