• Listen to a special audio message from Bill Roper to the Hive Workshop community (Bill is a former Vice President of Blizzard Entertainment, Producer, Designer, Musician, Voice Actor) 🔗Click here to hear his message!
  • Read Evilhog's interview with Gregory Alper, the original composer of the music for WarCraft: Orcs & Humans 🔗Click here to read the full interview.

[JASS] giving endblock missing error

Status
Not open for further replies.
Level 6
Joined
Aug 31, 2014
Messages
137
hey im been working on my map and learning jass on the way and got this error from enchanting the blink spell from warcraft 3 could someone look at it and see what im missing or did wrong?

[jass=my spell] function Trig_Demon_Blink_Conditions takes nothing returns boolean
if ( not ( GetSpellAbilityId() == 'A077' ) ) then
return false
endif
return true
endfunction

function Trig_Demon_Blink_Actions takes nothing returns nothing
local real X
local real Y
local unit hero
local unit target
local unit dummy
if GetSpellAbilityId () == 'A077' then
set hero = GetTriggerUnit ()
set target = GetSpellTargetUnit ()
set X = GetUnitX (target)
set Y = GetUnitY (target)
call SetUnitAnimation (hero , hero "attack 2" )
call SetUnitAnimation (target , target "death" )
if GetSpellTargetUnit == IsUnitEnemy returns TRUE then
set dummy = CreateUnit (GetTriggerPlayer , 'h00F' , X , Y, 1)
call SetUnitAnimation (hero , hero "attack 2" )
call SetUnitAnimation (target , target "death" )
call UnitDamageTargetBJ (hero ,target , 100 , ATTACK_TYPE_NORMAL , DAMAGE_TYPE_FORCE)
call IssueTargetOrder ( target , "attack" , hero )
if IsUnitType(target, UNIT_TYPE_HERO) == true ) ) then
call IssueTargetOrder (dummy , "stormbolt" , target )
call UnitApplyTimedLife (dummy , 'h00F' , 1 )
else
endif
return false
endfunction

//===========================================================================
function InitTrig_Demon_Blink takes nothing returns nothing
set gg_trg_Demon_Blink = CreateTrigger( )
call TriggerRegisterAnyUnitEventBJ( gg_trg_Demon_Blink, EVENT_PLAYER_UNIT_SPELL_EFFECT )
call TriggerAddCondition( gg_trg_Demon_Blink, Condition( function Trig_Demon_Blink_Conditions ) )
call TriggerAddAction( gg_trg_Demon_Blink, function Trig_Demon_Blink_Actions )
endfunction
[/code]


Edit: I know that the animations and ect are placed wrong
 
Last edited:
Always remember to end every "if" with an "endif"! :)

In Trig_Demon_Blink_Actions, you have 3 if statements, but only one endif. You have to place an endif for every if you have--so in your case, you would probably have two additional endif statements right before returns false.

Also, you have a return TRUE randomly inserted there. And unbalanced parentheses in this line:
if IsUnitType(target, UNIT_TYPE_HERO) == true ) ) then
Whenever you have an open parenthesis (, you must eventually have a ')' to close it, and it has to be in the right location. In the example above, you would have it like this:
if IsUnitType(target, UNIT_TYPE_HERO) == true then
That should parse just fine.

You also have too many arguments here:
JASS:
call SetUnitAnimation (hero , hero "attack 2" )
call SetUnitAnimation (target , target "death" )
If you look up the native SetUnitAnimation in the trigger editor's function list (assuming you have JassNewGenPack) or in the common.j, you'll notice that it has two arguments:
native SetUnitAnimation takes unit whichUnit, string whichAnimation returns nothing

So you would have to rewrite those statements like so:
JASS:
call SetUnitAnimation (hero , "attack 2" )
call SetUnitAnimation (target , "death" )

The following also will cause an error:
if GetSpellTargetUnit == IsUnitEnemy returns TRUE then
I assume you want it to mean "if the target unit is an enemy of the caster", so you would have to rewrite that line to:
if IsUnitEnemy(GetSpellTargetUnit(), GetTriggerPlayer()) then
GetTriggerPlayer() returns the triggering player, which in this case would be the player who casted the spell. Also note the parentheses after GetSpellTargetUnit--when you call a function, you have to use parentheses even if you aren't passing any information to it. Only variables can be written without parentheses.

There might be more errors, but I haven't checked that thoroughly. I recommend stepping down to a simple example, and working through it step by step. :) If you write a little bit of code, save and check for errors, it is usually pretty easy to correct. However, if you write a ton of code and don't check for errors until the end, you might have a bunch of errors and the error reporter might not give clear results. It is definitely frustrating, just keep at it and it'll become easier over time!
 
Level 6
Joined
Aug 31, 2014
Messages
137
Always remember to end every "if" with an "endif"! :)

In Trig_Demon_Blink_Actions, you have 3 if statements, but only one endif. You have to place an endif for every if you have--so in your case, you would probably have two additional endif statements right before returns false.

Also, you have a return TRUE randomly inserted there. And unbalanced parentheses in this line:
if IsUnitType(target, UNIT_TYPE_HERO) == true ) ) then
Whenever you have an open parenthesis (, you must eventually have a ')' to close it, and it has to be in the right location. In the example above, you would have it like this:
if IsUnitType(target, UNIT_TYPE_HERO) == true then
That should parse just fine.

You also have too many arguments here:
JASS:
call SetUnitAnimation (hero , hero "attack 2" )
call SetUnitAnimation (target , target "death" )
If you look up the native SetUnitAnimation in the trigger editor's function list (assuming you have JassNewGenPack) or in the common.j, you'll notice that it has two arguments:
native SetUnitAnimation takes unit whichUnit, string whichAnimation returns nothing

So you would have to rewrite those statements like so:
JASS:
call SetUnitAnimation (hero , "attack 2" )
call SetUnitAnimation (target , "death" )

The following also will cause an error:
if GetSpellTargetUnit == IsUnitEnemy returns TRUE then
I assume you want it to mean "if the target unit is an enemy of the caster", so you would have to rewrite that line to:
if IsUnitEnemy(GetSpellTargetUnit(), GetTriggerPlayer()) then
GetTriggerPlayer() returns the triggering player, which in this case would be the player who casted the spell. Also note the parentheses after GetSpellTargetUnit--when you call a function, you have to use parentheses even if you aren't passing any information to it. Only variables can be written without parentheses.

There might be more errors, but I haven't checked that thoroughly. I recommend stepping down to a simple example, and working through it step by step. :) If you write a little bit of code, save and check for errors, it is usually pretty easy to correct. However, if you write a ton of code and don't check for errors until the end, you might have a bunch of errors and the error reporter might not give clear results. It is definitely frustrating, just keep at it and it'll become easier over time!

thank you for helping but we seem to run into other error says an unspected return false i made the other changes that you had said
[jass=myspell] function Trig_Demon_Blink_Conditions takes nothing returns boolean
if ( not ( GetSpellAbilityId() == 'A077' ) ) then
return false
endif
return true
endfunction

function Trig_Demon_Blink_Actions takes nothing returns nothing
local real X
local real Y
local unit hero
local unit target
local unit dummy
if GetSpellAbilityId () == 'A077' then
set hero = GetTriggerUnit ()
set target = GetSpellTargetUnit ()
set X = GetUnitX (target)
set Y = GetUnitY (target)
if IsUnitEnemy(GetSpellTargetUnit(),GetTriggerPlayer ()) then
set dummy = CreateUnit (GetTriggerPlayer () , 'h00F' , X , Y, 1)
call UnitDamageTargetBJ (hero ,target , 100 , ATTACK_TYPE_NORMAL , DAMAGE_TYPE_FORCE)
call IssueTargetOrder ( target , "attack" , hero )
call SetUnitAnimation (target , "death")
call SetUnitAnimation (hero , "attack 2")
else
if IsUnitType(target, UNIT_TYPE_HERO) == true then
call IssueTargetOrder (dummy , "stormbolt" , target )
call UnitApplyTimedLife (dummy , 'h00F' , 1 )
else
endif
endif
endif
returns false
endfunction
[/code]
 
Level 17
Joined
Dec 11, 2014
Messages
2,004

  • Remove the returns false in Trig_Demon_Blink_Actions at the end. The function takes nothing returns "Nothing"! Also, if you want to skip remaining actions use an empty return before where you want to skip, like:
    JASS:
    function testy takes nothing returns nothing
     if udg_aninteger == 1 then
      return
     endif
     //the function will NOT ser udg_anotherinteger to 13 if udg_aninteger isn't equal to 1.
     set udg_anotherinteger = 13
    endfunction
  • You already have the local variable target, why again use GetSpellTargetUnit() in the if?
  • Remove the Last else. It Does NOTHING.
  • in the first else (the one that works) dummy does not exist to work. AND it does nothing in the first if.
  • the whole thing can be easily done in GUI. no need for JASS.
  • What are you trying to achieve? Please say and we can help you.

Hope this helps :D
 
Level 6
Joined
Aug 31, 2014
Messages
137
it now save but now it does not summion the dummy which stuns the target...... and i have all the right spellid and the spell if based off channel this is a blink spell that is enchanced does damage taughts creeps and stuns hero
[jass=blink] function Trig_Demon_Blink_Conditions takes nothing returns boolean
if ( not ( GetSpellAbilityId() == 'A078' ) ) then
return false
endif
return true
endfunction

function Trig_Demon_Blink_Actions takes nothing returns nothing
local real X
local real Y
local unit hero
local unit target
local unit dummy
local player owner
if GetSpellAbilityId () == 'A078' then
set hero = GetTriggerUnit ()
set target = GetSpellTargetUnit ()
set X = GetUnitX (target)
set Y = GetUnitY (target)
set owner = GetTriggerPlayer ()
if IsUnitEnemy(GetSpellTargetUnit(),owner) then
call UnitDamageTargetBJ (hero ,target , 100 , ATTACK_TYPE_NORMAL , DAMAGE_TYPE_FORCE)
call IssueTargetOrder ( target , "attack" , hero )
call SetUnitPosition (hero , X , Y )
call SetUnitAnimation (target , "death")
call SetUnitAnimation (hero , "attack 2")
if IsUnitType(target, UNIT_TYPE_HERO) == TRUE then
set dummy = CreateUnit (GetTriggerPlayer() , 'h00F' , X , Y, 1)
call IssueTargetOrder (dummy , "stormbolt" , target )
call UnitApplyTimedLife (dummy , 'h00F' , 1 )
return
endif
endif
endif
endfunction[/code]


and i feel that jass is quicker and more effect then gui. I dont want to look around for the gui templates when i can just type it in function list or on the script its self
 
According to your trigger's logic, it will only create the dummy and stun the enemy unit if the target is a hero. Maybe you meant to have the opposite?

If that is the case, then you should change this:
if IsUnitType(target, UNIT_TYPE_HERO) == TRUE then
To this:
if IsUnitType(target, UNIT_TYPE_HERO) == false then
(instead of TRUE and FALSE, you can just write true or false)

Also, was the target damaged at all? If the unit isn't being damaged at all, then one of the earlier conditions isn't being passed. How can we debug this? In JASS, you'll find yourself using game messages a lot. It provides us with two things:
(1) we can tell if our code has reached a certain point (the code can get errors along the way and fail to recover, or sometimes you'll have if-conditions that aren't evaluated because of some mistake in your code)
(2) we can print values (e.g. damage, unit names, etc.) to make sure that they are all functioning as expected

Usually we'll use call BJDebugMsg("Hello!"), where Hello! is the message that will display on the screen. Try putting that in your code. Put one line after UnitDamageTarget that says this:
call BJDebugMsg("Damage!")
Then put a line after set dummy = CreateUnit(...) that says this:
call BJDebugMsg("Created dummy!")

Test it out ingame. If you see the "Damage!" message, then you know that the spell successfully ran the damage function. If you see "Created dummy!", then you know that the spell successfully created the dummy unit. If you didn't see the "Damage!" or "Created dummy!" text, then you know something went wrong before that. Debugging involves a lot of testing--but it is worth it in the end.
 
Level 6
Joined
Aug 31, 2014
Messages
137
According to your trigger's logic, it will only create the dummy and stun the enemy unit if the target is a hero. Maybe you meant to have the opposite?

If that is the case, then you should change this:
if IsUnitType(target, UNIT_TYPE_HERO) == TRUE then
To this:
if IsUnitType(target, UNIT_TYPE_HERO) == false then
(instead of TRUE and FALSE, you can just write true or false)

Also, was the target damaged at all? If the unit isn't being damaged at all, then one of the earlier conditions isn't being passed. How can we debug this? In JASS, you'll find yourself using game messages a lot. It provides us with two things:
(1) we can tell if our code has reached a certain point (the code can get errors along the way and fail to recover, or sometimes you'll have if-conditions that aren't evaluated because of some mistake in your code)
(2) we can print values (e.g. damage, unit names, etc.) to make sure that they are all functioning as expected

Usually we'll use call BJDebugMsg("Hello!"), where Hello! is the message that will display on the screen. Try putting that in your code. Put one line after UnitDamageTarget that says this:
call BJDebugMsg("Damage!")
Then put a line after set dummy = CreateUnit(...) that says this:
call BJDebugMsg("Created dummy!")

Test it out ingame. If you see the "Damage!" message, then you know that the spell successfully ran the damage function. If you see "Created dummy!", then you know that the spell successfully created the dummy unit. If you didn't see the "Damage!" or "Created dummy!" text, then you know something went wrong before that. Debugging involves a lot of testing--but it is worth it in the end.

yea i worked on it a bit and now
[jass=spell] function Trig_Demon_Blink_Conditions takes nothing returns boolean
if ( not ( GetSpellAbilityId() == 'A078' ) ) then
return false
endif
return true
endfunction

function Trig_Demon_Blink_Actions takes nothing returns nothing
local real X
local real Y
local unit hero
local unit target
local unit dummy
local player owner
if GetSpellAbilityId () == 'A078' then
set hero = GetTriggerUnit ()
set target = GetSpellTargetUnit ()
set X = GetUnitX (target)
set Y = GetUnitY (target)
set owner = GetTriggerPlayer ()
if IsUnitEnemy(GetSpellTargetUnit(),owner) then
call UnitDamageTargetBJ (hero ,target , 100 , ATTACK_TYPE_NORMAL , DAMAGE_TYPE_FORCE)
call IssueTargetOrder ( target , "attack" , hero )
call SetUnitPosition (hero , X , Y )
call SetUnitAnimation (target , "death")
call SetUnitAnimation (hero , "attack 2")
if IsUnitType(target, UNIT_TYPE_HERO) == TRUE then
set dummy = CreateUnit (GetTriggerPlayer (), 'h00M' , X , Y , 1)
call PolledWait (0.50)
call IssueTargetOrder (dummy , "stormbolt" , GetSpellTargetUnit () )
call PolledWait (0.50)
call UnitApplyTimedLife (dummy , 'BTLF' , 1)
set dummy = null
set hero = null
set target = null
set owner = null
return
endif
endif[/code]


but even with me calling the dummy which is created now. wont use the storm bolt or get the applyed timelife and damage is happening
edit: i got the timed life to apper on the dummy but still no cast z.z
 
Last edited:
Status
Not open for further replies.
Top