• 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] Newbie Neds help :)

Status
Not open for further replies.
Level 1
Joined
Oct 7, 2012
Messages
7
so i decided to learn JASS, I understand the general idea and when i see a basic script i can understand what the elements do. BUT i can't manage to get them right myself. here is the code, im trying to learn JASS so i don't care if sombody yells at me because i can only learn right :). I got loads of errors when trying to test my map. The script is for a (basic?) heal spell. but i don't know if i used the 'Ahea' thing right. (took it from the heal spell in the object manager) I created this script by looking at many tutorials on this site, it's not a copy i wrote everything myself but i looked at the tuts to get a general idea on how to set it up(if that makes sence?:eekani:)

JASS:
function Cond takes nothing returns boolean
 return GetSpellAbilityId()=='Ahea'
endfunction

function Action takes nothing returns real heal
local unit caster
local real heal
local integer level


set caster = GetTriggerUnit()

set level = GetHeroLevel(caster)

if level < 2 then
    set heal = 30.
  elseif level == 2 then
    set heal = 35.
  elseif level == 3 then
    set heal = 45.
  return heal
  endif 
endfunction  
      
//---------------------------------------------------

function InitTrig_heal takes nothing returns nothing
local trigger t
set t =CreateTrigger()

call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT)
call TriggerAddCondition(t Condition(function Cond))
call TriggerAddAction(t, function Action)
endfunction

hope sombody wants to tell me what is wrong here :)
thanks!
 
Level 28
Joined
Jan 26, 2007
Messages
4,789
Code:
1) The 'Ahea' is the raw ID of an ability ('Ahea' is the standard priest heal-ability).
To view raw ID's, press CTRL + D in the object editor. Once you have found your spell, look at the Raw ID (always a 4-character code) and insert it between the apostrophe's.


2) Please use the tab-key more often and don't place too many enters when it isn't needed :)
Personally, I write code like this:
JASS:
function hello takes nothing returns nothing
	local integer i = 0
	local unit u
	
	loop
		exitwhen i == 5
		set i = i+1
		set u = CreateUnit( Player(i), 'hfoo', 0., 0., 0. )
	endloop
	
	set u = null
endfunction

I find it a lot more readable than, say, this:
JASS:
function hello takes nothing returns nothing
local integer i=0
local unit u
loop
 exitwhen i==5
 set i=i+1
 set u=CreateUnit(Player(i),'hfoo',0.,0.,0.)
endloop
set u=null
endfunction

It's the exact same thing, but also kinda different :D
I'm not going to teach you where to put spaces and enters and tabs and all that, but just make sure that other people can actually read your code.


3) About your variables: you can initialize variables while declaring them
(Declaration: things like "local integer i", this declares the variable i).
What you do:
JASS:
local unit caster
local real heal
local integer level


set caster = GetTriggerUnit()

set level = GetHeroLevel(caster)

How it could have been done:
JASS:
local unit caster = GetTriggerUnit()
local integer level = GetHeroLevel(caster)
local real heal


4) About your events: most people will prefer that you not use BJ's (the code in red).
What you did:
JASS:
call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT)

How it could have been done:
JASS:
local integer i = 0

loop
    exitwhen i == 16
    call TriggerRegisterPlayerUnitEvent(t, Player(i), EVENT_PLAYER_UNIT_SPELL_EFFECT, null)
    set i = i+1
endloop


5) Using ITE's (If Then Else's) efficiently
What you did:
JASS:
if level < 2 then
    set heal = 30.
elseif level == 2 then
    set heal = 35.
elseif level == 3 then
    set heal = 45.
endif

How it could have been done (I actually know of 2 ways, I'm just going to show you this one):
JASS:
if level == 1 then
    set heal = 30.
elseif level == 2 then
    set heal = 35.
else
    set heal = 45.
endif
Not that much of a change, but it's aesthetically more pleasing :)
The other one was where you leave out the "else"-section altogether and place "set heal = 45." in front of the ITE.



6) Nulling variables.
Certain variable types have to be nulled after being used, unit variables are one of them (basically: null everything except for booleans, integers and reals - I may be forgetting something though).
At the end of the trigger, simply do: set caster = null.
Note that you have to do this before returning anything (otherwise it won't be nulled either).


7) The mistakes :D

I'll start with a silly one: you forgot a comma.
JASS:
call TriggerAddCondition(t Condition(function Cond))
There should be a comma between "t" and "Condition(...)".

Then we come to the next problem:
JASS:
if level < 2 then
    set heal = 30.
elseif level == 2 then
    set heal = 35.
elseif level == 3 then
    set heal = 45.
    return heal
endif
You only return a value if the level equals 3.
For all the other values, you never return anything. This will cause errors, as the function specifically says that it will return an integer (which it doesn't do unless the level is 3).

The simple solution would be:
JASS:
if level == 1 then
    set heal = 30.
elseif level == 2 then
    set heal = 35.
else
    set heal = 45.
endif
return heal


Oh, and something else which I *think* is a mistake:
the variable "level" should probably be set to "GetUnitAbilityLevel( caster, GetSpellAbilityId() )" (so you get the level of the casted ability, not the level of the hero).

And as a last thing: the trigger doesn't actually heal anything, I don't know if it was a work-in-progress or not so I'm going to let you finish that if you so desire :)

I think that's it, happy coding.
 
Level 40
Joined
Dec 14, 2005
Messages
10,532
4) About your events: most people will prefer that you not use BJ's (the code in red).
What you did:
JASS:
call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT)

How it could have been done:
JASS:
local integer i = 0

loop
    exitwhen i == 16
    call TriggerRegisterPlayerUnitEvent(t, Player(i), EVENT_PLAYER_UNIT_SPELL_EFFECT, null)
    set i = i+1
endloop

TriggerRegisterAnyUnitEventBJ is fine and inlining it is kind of pointless and annoying. Some people whine about use of any BJs, but those people aren't worth listening to; don't use most of them because they're useless and suck, but some are useful.
 
Level 1
Joined
Oct 7, 2012
Messages
7
Thank you!

Thank you very much for pointing all those mistakes out :D now i still get most of the errors i got before and i don't understand why:eekani:, so I will poste the new code where i tried to follow up on what you said (nevermind it looking messy for now)

the code:
JASS:
function Cond takes nothing returns boolean
 return GetSpellAbilityId()=='Ahea'
endfunction

function Action takes nothing returns real heal
    local unit caster = GetTriggerUnit()
    local integer level = GetHeroLevel(caster)
    local real heal

if level == 1 then
    set heal = 30.
  elseif level == 2 then
    set heal = 35.
  else 
    set heal = 45.
  endif 
  return heal
endfunction  
      
//---------------------------------------------------

function InitTrig_heal takes nothing returns nothing
local trigger t
set t =CreateTrigger()

    call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT)
    call TriggerAddCondition(t, Condition(function Cond))
    call TriggerAddAction(t, function Action)
endfunction

Then the errors:

JASS:
Line34: Expected end of line
Line35: Expected end of line
Line36: Expected end of line
Line37: Expected end of line
Line39: Expected a name
Line40: Expected a variable name
Line41: Expected a code statement
Line42: Expected a code statement
Line43: Expected a code statement
Line44: Expected a variable name
Line45: Expected a code statement
Line46: Expected a name
Line46: Expected a code statement
Line50: Expected a code statement
Line51: Expected a code statement
Line53: Expected a variable name
Line55: Expected a name
Line56: Expected a name
Line57: Expected a name
Line57: Expected a code statement

I don't know why it says line 34 throug 57, but i figured that line 34 is line one :) I know this is much to ask (to read all that crap) but i hope you atleast can help me understand why i get those errors

Thanks again :)
 
Level 1
Joined
Oct 7, 2012
Messages
7
i used teh get hero level thing because i wanted to have the level of the hero determin the power of the spell :)
 
Level 40
Joined
Dec 14, 2005
Messages
10,532
JASS:
local trigger t
set t =CreateTrigger()

Can be local trigger t = CreateTrigger()

The error is coming from the fact that you are naming your return value. Don't, just use returns real. That said, this won't actually do anything; if the spell cast is 'Ahea', it'll just return 30/35/45 (which nothing will track) and end.
 
Level 1
Joined
Oct 7, 2012
Messages
7
Thank you very much. I thougt my entire code was wrong, one little thing that broke the wole thing:O
I sure learned somthing :D
now i have to make it do somthing :) if i have any other errors that i cant resolve i will ask again (if that is okay :p)
 
Level 1
Joined
Oct 7, 2012
Messages
7
let's say i would like to use the returnet Real value form function Action... how would i do that?

what im trying to do is to send out a text that says "this will heal" and then the amount

in other languages i know i can use: "textehere" and Variablehere

but that was hust an example, just to clerify thing: my question how do i use the returned value

Edit: one more thing how can i make the spell unclickable when the hero has full HP ?
 
Last edited:
Level 28
Joined
Jan 26, 2007
Messages
4,789
You don't have to use returned values for that, but if you really want to:

JASS:
function checkLevel takes nothing returns real
    local unit caster = GetTriggerUnit()
    local integer level = GetHeroLevel(caster)
    local real heal

    if level == 1 then
        set heal = 30.
    elseif level == 2 then
        set heal = 35.
    else 
        set heal = 45.
    endif 
    return heal
endfunction  

function Action takes nothing returns nothing
    call DisplayTextToPlayer( GetOwningPlayer(GetTriggerUnit()), 0., 0., "This will heal " + R2S(checkLevel()) )
endfunction
Since the function returns a real, you need to treat it as one, so I used the R2S (Real to String).
You can do this for anything
Some examples would be:
call RemoveUnit( getRandomUnit() ) (with function getRandomUnit takes nothing returns unit).
local integer killCount = getKillCount( GetPlayerId( GetTriggerPlayer() ) ) (with function getKillCount takes integer i returns integer).


Edit: oh, and you can base the ability on the spell "Item Healing". I think it won't work when the hero has full HP.
 
Level 1
Joined
Oct 7, 2012
Messages
7
thanks again :) i love you people!
now i (think I) have made a healing spell the code is:
JASS:
function Trig_Untitled_Trigger_002_Actions takes nothing returns nothing
endfunction

//===========================================================================
function InitTrig_HealSpell takes nothing returns nothing
    set gg_trg_HealSpell = CreateTrigger(  )
    call TriggerAddAction( gg_trg_HealSpell, function Trig_Untitled_Trigger_002_Actions )
endfunction

function Cond takes nothing returns boolean
 return GetSpellAbilityId()=='Ahea'
endfunction

function Action takes nothing returns nothing
    local unit caster = GetTriggerUnit()
    local integer level = GetHeroLevel(caster)
    local real heal
    local real HeroHP = GetUnitState(caster, UNIT_STATE_LIFE)
    local real HeroMaxHp = GetUnitState(caster, UNIT_STATE_MAX_LIFE)
if level == 1 then
    set heal = 30.
  elseif level == 2 then
    set heal = 35.
  else 
    set heal = 45.
  endif 

if HeroHp < HeroMaxHp then
    call SetUnitState (caster, UNIT_STATE_LIFE, HeroHP + heal)
    else DoNothing   
    
    endif 
endfunction 
   
      
//---------------------------------------------------

function InitTrig_heal takes nothing returns nothing
local trigger t = CreateTrigger()

    call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT)
    call TriggerAddCondition(t, Condition(function Cond))
    call TriggerAddAction(t, function Action)
endfunction

But as always i would not have posted this if there wasn't an issue:/
the error ocurs in line 57: Expected a name
this is the problem
JASS:
if HeroHp < HeroMaxHp then
so... yeah
for the fourth time ThankYou!
 
Last edited:
Remember, JASS is case sensitive. So when you define HeroHP:
JASS:
local real HeroHP = ...
You can't have it as HeroHp. Remember, HeroHP, HErOHp, HeRoHp, HeroHp are all different names, and therefore they refer to different things.
Therefore, change it to:
JASS:
if HeroHP < HeroMaxHp then

The other problem is your 'else' line.
JASS:
 else DoNothing
You have to put DoNothing on a separate line. So it would be like this:
JASS:
else 
   call DoNothing()
endif
Or better yet, why not just exclude the 'else' since you aren't going to do anything anyway?
JASS:
if HeroHP < HeroMaxHp then
    call SetUnitState (caster, UNIT_STATE_LIFE, HeroHP + heal)
endif

Hopefully that should fix the errors. :)
 
Level 1
Joined
Oct 7, 2012
Messages
7
thank you that fixed it:) however ingame i can't cklick on the custom ability i linked to the script:/ it looks like an active effect
 
Status
Not open for further replies.
Top