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

[JASS] " Expected ' "

Status
Not open for further replies.
Level 3
Joined
Dec 22, 2007
Messages
35
Hello, I'm having trouble setting up this trigger because line 51 is giving me errors (it's underlined/italicized/bolded). It says " Expected ' " when I call this. All I'm trying to figure out is how to convert GUI to Jass to avoid the use of excessive global variables. If someone can help me figure out this scenario I can probably figure out the rest.

Thanks!

JASS:
function Trig_DischargeTarget_Copy_Func003C takes nothing returns boolean
    if ( ( 'A005' == GetSpellAbilityId() ) ) then
        return true
    endif
    if ( ( 'A006' == GetSpellAbilityId() ) ) then
        return true
    endif
    if ( ( 'A001' == GetSpellAbilityId() ) ) then
        return true
    endif
    if ( ( 'A003' == GetSpellAbilityId() ) ) then
        return true
    endif
    return false
endfunction

function Trig_DischargeTarget_Copy_Conditions takes nothing returns boolean
    if ( not Trig_DischargeTarget_Copy_Func003C() ) then
        return false
    endif
    return true
endfunction

function Trig_DischargeTarget_Copy_Func006A takes unit Discharge_Target returns nothing
    call UnitAddAbilityBJ( 'A004', GetEnumUnit() )
    call SetUnitAbilityLevelSwapped( 'A004', GetEnumUnit(), GetUnitAbilityLevelSwapped(GetSpellAbilityId(), GetTriggerUnit()) )
    call IssueTargetOrderBJ( GetEnumUnit(), "chainlightning", Discharge_Target )
    call AddSpecialEffectTargetUnitBJ( "chest", GetEnumUnit(), "Abilities\\Spells\\Human\\Resurrect\\ResurrectCaster.mdl" )
    set udg_CotR_effects[udg_Discharge_Effects] = GetLastCreatedEffectBJ()
    set udg_Discharge_Effects = ( udg_Discharge_Effects + 1 )
endfunction

function Trig_DischargeTarget_Copy_Func008A takes nothing returns nothing
    call RemoveUnit( GetEnumUnit() )
    call DestroyEffectBJ( udg_CotR_effects[udg_Discharge_Effects] )
    set udg_Discharge_Effects = ( udg_Discharge_Effects - 1 )
endfunction

function Trig_DischargeTarget_Copy_Actions takes nothing returns nothing
    local unit Discharge_Target = GetSpellTargetUnit()
    call SetUnitLifeBJ( GetTriggerUnit(), ( GetUnitStateSwap(UNIT_STATE_LIFE, GetTriggerUnit()) - 80.00 ) )
    set bj_forLoopAIndex = 0
    set bj_forLoopAIndexEnd = 5
    loop
        exitwhen bj_forLoopAIndex > bj_forLoopAIndexEnd
        call CreateNUnitsAtLocFacingLocBJ( 1, 'e000', GetOwningPlayer(GetTriggerUnit()), PolarProjectionBJ(GetUnitLoc(GetSpellTargetUnit()), 250.00, ( I2R(GetForLoopIndexA()) * 60.00 )), GetUnitLoc(GetSpellTargetUnit()) )
        call GroupAddUnitSimple( GetLastCreatedUnit(), udg_LightningGroup )
        set bj_forLoopAIndex = bj_forLoopAIndex + 1
    endloop
    call TriggerSleepAction( 3.00 )
    [U][I][B]call ForGroupBJ( udg_LightningGroup, function Trig_DischargeTarget_Copy_Func006A(Discharge_Target) )[/B][/I][/U]
    call TriggerSleepAction( 1.20 )
    call ForGroupBJ( udg_LightningGroup, function Trig_DischargeTarget_Copy_Func008A )
endfunction

//===========================================================================
function InitTrig_DischargeTarget_Copy takes nothing returns nothing
    set gg_trg_DischargeTarget_Copy = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_DischargeTarget_Copy, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddCondition( gg_trg_DischargeTarget_Copy, Condition( function Trig_DischargeTarget_Copy_Conditions ) )
    call TriggerAddAction( gg_trg_DischargeTarget_Copy, function Trig_DischargeTarget_Copy_Actions )
endfunction
 
Last edited by a moderator:

Dr Super Good

Spell Reviewer
Level 64
Joined
Jan 18, 2005
Messages
27,202
JASS:
function Trig_DischargeTarget_Copy_Func003C takes nothing returns boolean
    if ( ( 'A005' == GetSpellAbilityId() ) ) then
        return true
    endif
    if ( ( 'A006' == GetSpellAbilityId() ) ) then
        return true
    endif
    if ( ( 'A001' == GetSpellAbilityId() ) ) then
        return true
    endif
    if ( ( 'A003' == GetSpellAbilityId() ) ) then
        return true
    endif
    return false
endfunction

function Trig_DischargeTarget_Copy_Conditions takes nothing returns boolean
    if ( not Trig_DischargeTarget_Copy_Func003C() ) then
        return false
    endif
    return true
endfunction

function Trig_DischargeTarget_Copy_Func006A takes unit Discharge_Target returns nothing
    //Problem with part of above line "takes unit Discharge_Target "
    //Such a function as one run in the for group function has to take and return no values inorder to work.
    call UnitAddAbilityBJ( 'A004', GetEnumUnit() )
    call SetUnitAbilityLevelSwapped( 'A004', GetEnumUnit(), GetUnitAbilityLevelSwapped(GetSpellAbilityId(), GetTriggerUnit()) )
    call IssueTargetOrderBJ( GetEnumUnit(), "chainlightning", Discharge_Target )
    call AddSpecialEffectTargetUnitBJ( "chest", GetEnumUnit(), "Abilities\\Spells\\Human\\Resurrect\\ResurrectCaster.mdl" )
    set udg_CotR_effects[udg_Discharge_Effects] = GetLastCreatedEffectBJ()
    set udg_Discharge_Effects = ( udg_Discharge_Effects + 1 )
endfunction

function Trig_DischargeTarget_Copy_Func008A takes nothing returns nothing
    call RemoveUnit( GetEnumUnit() )
    call DestroyEffectBJ( udg_CotR_effects[udg_Discharge_Effects] )
    set udg_Discharge_Effects = ( udg_Discharge_Effects - 1 )
endfunction

function Trig_DischargeTarget_Copy_Actions takes nothing returns nothing
    local unit Discharge_Target = GetSpellTargetUnit()
    call SetUnitLifeBJ( GetTriggerUnit(), ( GetUnitStateSwap(UNIT_STATE_LIFE, GetTriggerUnit()) - 80.00 ) )
    set bj_forLoopAIndex = 0
    set bj_forLoopAIndexEnd = 5
    loop
        exitwhen bj_forLoopAIndex > bj_forLoopAIndexEnd
        call CreateNUnitsAtLocFacingLocBJ( 1, 'e000', GetOwningPlayer(GetTriggerUnit()), PolarProjectionBJ(GetUnitLoc(GetSpellTargetUnit()), 250.00, ( I2R(GetForLoopIndexA()) * 60.00 )), GetUnitLoc(GetSpellTargetUnit()) )
        call GroupAddUnitSimple( GetLastCreatedUnit(), udg_LightningGroup )
        set bj_forLoopAIndex = bj_forLoopAIndex + 1
    endloop
    call TriggerSleepAction( 3.00 )
    call ForGroupBJ( udg_LightningGroup, function Trig_DischargeTarget_Copy_Func006A(Discharge_Target) )
    //Problem with part of above line "function Trig_DischargeTarget_Copy_Func006A(Discharge_Target)"
    //Can not give a value to a function when executed in this way because it basically runs that function for each unit in the group
    //If a value was able to be given the function would be a lot more demanding and hard to program so they did not allow it as also it would make no sense
    call TriggerSleepAction( 1.20 )
    call ForGroupBJ( udg_LightningGroup, function Trig_DischargeTarget_Copy_Func008A )
endfunction

//===========================================================================
function InitTrig_DischargeTarget_Copy takes nothing returns nothing
    set gg_trg_DischargeTarget_Copy = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_DischargeTarget_Copy, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddCondition( gg_trg_DischargeTarget_Copy, Condition( function Trig_DischargeTarget_Copy_Conditions ) )
    call TriggerAddAction( gg_trg_DischargeTarget_Copy, function Trig_DischargeTarget_Copy_Actions )
endfunction

Do not worry, for your own sake I fixed the syntax problem while keeping it functioning like you wanted as well as making it overall more efficent, however leaks still happen and I have not bothered removing them. I hape left a comment below a line that leaks a lot of locations.

JASS:
function Trig_DischargeTarget_Copy_Conditions takes nothing returns boolean
    return 'A005' == GetSpellAbilityId() or 'A006' == GetSpellAbilityId() or 'A001' == GetSpellAbilityId() or 'A003' == GetSpellAbilityId()
endfunction

function Trig_DischargeTarget_Copy_Func008A takes nothing returns nothing
    call RemoveUnit(GetEnumUnit())
    call DestroyEffect( udg_CotR_effects[udg_Discharge_Effects] )
    set udg_Discharge_Effects = ( udg_Discharge_Effects - 1 )
endfunction

function Trig_DischargeTarget_Copy_Actions takes nothing returns nothing
    local unit Discharge_Target = GetSpellTargetUnit()
    local unit u
    local group g = CreateGroup()
    call SetUnitLifeBJ( GetTriggerUnit(), ( GetUnitStateSwap(UNIT_STATE_LIFE, GetTriggerUnit()) - 80.00 ) )
    set bj_forLoopAIndex = 0
    set bj_forLoopAIndexEnd = 5
    loop
        exitwhen bj_forLoopAIndex > bj_forLoopAIndexEnd
        call CreateNUnitsAtLocFacingLocBJ( 1, 'e000', GetOwningPlayer(GetTriggerUnit()), PolarProjectionBJ(GetUnitLoc(GetSpellTargetUnit()), 250.00, ( I2R(GetForLoopIndexA()) * 60.00 )), GetUnitLoc(GetSpellTargetUnit()) )
        //Above line leaks majorly as well as being unefficent, recomended to redo for your own maps sake
        call GroupAddUnitSimple( GetLastCreatedUnit(), udg_LightningGroup )
        set bj_forLoopAIndex = bj_forLoopAIndex + 1
    endloop
    call TriggerSleepAction( 3.00 )
    loop
        set u = FirstOfGroup(udg_LightningGroup)
        exitwhen u == null
        call GroupRemoveUnit(udg_LightningGroup,u)
        call GroupAddUnit(g,u)
        call UnitAddAbilityBJ( 'A004',u)
        call SetUnitAbilityLevelSwapped( 'A004',u, GetUnitAbilityLevelSwapped(GetSpellAbilityId(), GetTriggerUnit()) )
        call IssueTargetOrderBJ(u, "chainlightning", Discharge_Target )
        call AddSpecialEffectTargetUnitBJ( "chest",u, "Abilities\\Spells\\Human\\Resurrect\\ResurrectCaster.mdl" )
        set udg_CotR_effects[udg_Discharge_Effects] = GetLastCreatedEffectBJ()
        set udg_Discharge_Effects = ( udg_Discharge_Effects + 1 )
    endloop
    call DestroyGroup(udg_LightningGroup)
    set udg_LightningGroup = g
    call TriggerSleepAction( 1.20 )
    call ForGroupBJ( udg_LightningGroup, function Trig_DischargeTarget_Copy_Func008A )
    set Discharge_Target = null
    set g = null
endfunction

function InitTrig_DischargeTarget_Copy takes nothing returns nothing
    set gg_trg_DischargeTarget_Copy = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_DischargeTarget_Copy, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddCondition( gg_trg_DischargeTarget_Copy, Condition( function Trig_DischargeTarget_Copy_Conditions ) )
    call TriggerAddAction( gg_trg_DischargeTarget_Copy, function Trig_DischargeTarget_Copy_Actions )
endfunction

Good luck.
 
Level 3
Joined
Dec 22, 2007
Messages
35
First off, thank you dr super good for helping me out so much. Your information was invaluable : ) However, I had one last question about what you said about the memory leak. I don't understand why that line of code would create memory leaks as we remove those units later. Could you give me just a little more insight as to why that line of code creates a memory leak? Thanks so much for your assistance once again!!


For educational purposes, here is the resulting code I arrived at which removed all global variables and fixing a few things:

JASS:
function Trig_DischargeTarget_Copy_Conditions takes nothing returns boolean
    return 'A005' == GetSpellAbilityId() or 'A006' == GetSpellAbilityId() or 'A001' == GetSpellAbilityId() or 'A003' == GetSpellAbilityId()
endfunction

function Trig_DischargeTarget_Copy_Func008A takes nothing returns nothing
    call RemoveUnit(GetEnumUnit())
endfunction

function Trig_DischargeTarget_Copy_Actions takes nothing returns nothing
    local unit Discharge_Target = GetSpellTargetUnit()
    local unit Temp_Unit
    local group Discharge_Group = CreateGroup()
    local group Temp_Group = CreateGroup()
    local effect array Discharge_Effects
    local integer Discharge_Index = 0                 
    
    call SetUnitLifeBJ( GetTriggerUnit(), ( GetUnitStateSwap(UNIT_STATE_LIFE, GetTriggerUnit()) - 80.00 ) )
    
    set bj_forLoopAIndex = 0
    set bj_forLoopAIndexEnd = 5
    loop
        exitwhen bj_forLoopAIndex > bj_forLoopAIndexEnd
        call CreateNUnitsAtLocFacingLocBJ( 1, 'e000', GetOwningPlayer(GetTriggerUnit()), PolarProjectionBJ(GetUnitLoc(GetSpellTargetUnit()), 250.00, ( I2R(GetForLoopIndexA()) * 60.00 )), GetUnitLoc(GetSpellTargetUnit()) )
        //Above line leaks majorly as well as being unefficent, recomended to redo for your own maps sake
        call GroupAddUnitSimple( GetLastCreatedUnit(), Discharge_Group )
        set bj_forLoopAIndex = bj_forLoopAIndex + 1
    endloop
    
    
    call TriggerSleepAction( 3.00 )
    
    loop
        set Temp_Unit = FirstOfGroup(Discharge_Group)
        exitwhen Temp_Unit == null
        call GroupRemoveUnit(Discharge_Group,Temp_Unit)
        call GroupAddUnit(Temp_Group,Temp_Unit)
        call UnitAddAbilityBJ( 'A004',Temp_Unit)
        call SetUnitAbilityLevelSwapped( 'A004',Temp_Unit, GetUnitAbilityLevelSwapped(GetSpellAbilityId(), GetTriggerUnit()) )
        call IssueTargetOrderBJ(Temp_Unit, "chainlightning", Discharge_Target )
        call AddSpecialEffectTargetUnitBJ( "chest",Temp_Unit, "Abilities\\Spells\\Human\\Resurrect\\ResurrectCaster.mdl" )
        set Discharge_Effects[Discharge_Index] = GetLastCreatedEffectBJ()
        set Discharge_Index = ( Discharge_Index + 1 )
    endloop
    
    
    call TriggerSleepAction( 1.20 )
    call ForGroupBJ( Temp_Group, function Trig_DischargeTarget_Copy_Func008A )
    
    
    loop
        exitwhen Discharge_Index == 0
        call DestroyEffect( Discharge_Effects[Discharge_Index] )
        set Discharge_Effects[Discharge_Index] = null
        set Discharge_Index = ( Discharge_Index - 1 )    
    endloop
    
    set Discharge_Target = null
    set Temp_Group = null
    set Discharge_Group = null
    set Temp_Group = null
endfunction

    //==============================================Event
function InitTrig_DischargeTarget_Copy takes nothing returns nothing
    set gg_trg_DischargeTarget_Copy = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_DischargeTarget_Copy, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddCondition( gg_trg_DischargeTarget_Copy, Condition( function Trig_DischargeTarget_Copy_Conditions ) )
    call TriggerAddAction( gg_trg_DischargeTarget_Copy, function Trig_DischargeTarget_Copy_Actions )
endfunction
 
Level 20
Joined
Apr 22, 2007
Messages
1,960
Mhm, you're creating locations without removing them. This sort of thing happens with handles in Warcraft III. Handles are every type in Wc3, except real, integer, boolean, string, code. So whenever you create temporary handles, be sure to remove them (not ALL handles though. Never remove things like BoolExpr's and Players :p). So when you're using PolarProjectionBJ or something like that, you're leaking a location. To fix this, get a local location, set it to the polar projection, do everything you need, and then remove the location using call RemoveLocation(yourlocationvariable).

One other things, try to avoid working with locations. It's much better to use coordinates (most native functions work with coordinates anyway). Here's how you could translate the PolarProjection function to coordinates:
So you have a point (x,y), and you want to project it with (d) distance towards (a) direction. The projected point will be (x2,y2). Here's the formula.

x2 = x + d * Cos(a)
y2 = y + d * Sin(a)

(a) must be an angle in radians, not degrees. To translate from degrees to radians, you multiply the angle by 3.14159/180, or bj_DEGTORAD in Warcraft III.

Any more problems? ;)
 
Level 3
Joined
Dec 22, 2007
Messages
35
I love you :D

I used only one location (the position of the target unit ) and just used coordinates all around him like you said with that formula. Then I destroyed that location. Thanks so much!!!
 
Status
Not open for further replies.
Top