• 🏆 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] Spell local variable problem

Status
Not open for further replies.
JASS:
function Trig_MindBlast_Conditions takes nothing returns boolean
    return GetSpellAbilityId() == 'A00B'
endfunction
function Trig_MindBlast_Func001C takes nothing returns boolean
return GetUnitAbilityLevelSwapped('A00B', GetTriggerUnit()) == 1
endfunction
function Trig_MindBlast_Actions takes nothing returns nothing
    if ( Trig_MindBlast_Func001C() ) then
        local real MindBlast_Stats
        local real MindBlast_Damage
        set MindBlast_Stats = I2R(GetHeroStatBJ(bj_HEROSTAT_INT, GetTriggerUnit(), true))
        set MindBlast_Damage = ( MindBlast_Stats + ( 0.20 * GetUnitStateSwap(UNIT_STATE_LIFE, GetSpellTargetUnit()) ) )
        call UnitDamageTargetBJ( GetTriggerUnit(), GetSpellTargetUnit(), MindBlast_Damage, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_NORMAL )
        call CreateTextTagLocBJ( R2S(MindBast_Damage), GetUnitLoc(GetSpellTargetUnit()), 0, 10, 100, 0.00, 100.00, 0 )
        call SetTextTagVelocityBJ( GetLastCreatedTextTag(), 50.00, 90 )
        call SetTextTagLifespanBJ( GetLastCreatedTextTag(), 2.00 )
        call SetTextTagPermanentBJ( GetLastCreatedTextTag(), false )

Guys when i put this in the program JassCraft, it says i have 4 errors ... why ?
Can anyone please tell me what is wrong ?
don't find what's wrong .. the problems are when i create and then set my real local variables ....
Another thing , is this spell MUI ? Because i think it is.... the use of locals makes him MUI...
 
Level 40
Joined
Dec 14, 2005
Messages
10,532
locals must be initialized at the start of the function.

3 more tips:

1) please post your entire spell next time, not half of it :p

2) you can inline that if-statement directly, eg:

if GetUnitAbilityLevel(GetTriggerUnit(),'A00B') == 1 then
...
endif

3) bjs are evil. Open your spell in JassCraft, and for each BJ you find, search it up in the Function Finder, view what the code does, and try to recreate it using natives. (note: not all bjs end with bj! There are Swap, Swapped, any GetLastCreated, and a few other things such as CreateNUnitsAtLoc (note: TriggerRegisterAnyUnitBJ is one of those Bjs that is actually useful)
 
Thx PurplePoot

I onyl have 1 error now ...

JASS:
//Here is the main condition
function Conditions takes nothing returns boolean
    return GetSpellAbilityId() == 'A00B'
endfunction
//Here is the condition that says that the level of the ability being cast is equal to 1
function Actions takes nothing returns boolean
     local real MindBlast_Stats = I2R(GetHeroStatBJ(bj_HEROSTAT_INT, GetTriggerUnit(), true))
     local real MindBlast_Damage = ( MindBlast_Stats + ( 0.20 * GetUnitStateSwap(UNIT_STATE_LIFE, GetSpellTargetUnit()) ) )
if GetUnitAbilityLevelSwapped('A00B', GetTriggerUnit()) == 1 then
        call UnitDamageTargetBJ( GetTriggerUnit(), GetSpellTargetUnit(), MindBlast_Damage, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_NORMAL )
        call CreateTextTagLocBJ( R2S(MindBlast_Damage), GetUnitLoc(GetSpellTargetUnit()), 0, 10, 100, 0.00, 100.00, 0 )
        call SetTextTagVelocityBJ( GetLastCreatedTextTag(), 50.00, 90 )
        call SetTextTagLifespanBJ( GetLastCreatedTextTag(), 2.00 )
        call SetTextTagPermanentBJ( GetLastCreatedTextTag(), false )
    return true
endif
endfunction
// the trigger stuff
function InitTrig_trigger takes nothing returns nothing
local trigger Blast = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ( Blast, EVENT_PLAYER_UNIT_SPELL_EFFECT)
call TriggerAddCondition(Blast, Condition(function Conditions))
call TriggerAddAction(Blast, function Actions) 
endfunction

I think that the locals are well done now ... I am not sure if the spell is MUI ... please tell me it is =S.

However i have one last error ... JassCraft says that:
JassCraft said:
Return types not correct or nonexistant returns
and it points this return problem was an important error i can't solve ...

Another thing i don't understand - Why are Bj functions evil ?? i know they are slower sometimes but this is my first spell at JASS and i don't know everything yet .. What is the problem with BJ ?
Also how can i replace Bj functions ?
- I notest in my Jass program that there are two equal function:
1. UnitDamageTarget
2. UnitDamageTargetBJ

What are the differences between these two functions ?? Just the name ???

Please i posted like 90% of my spell, i don't want you guys to tell me everything, i want to learn so i can create my own spells, but please tell me if it is MUI, leak free and most important of all, please tell me why it doesn't work =(
 
Last edited:
Level 10
Joined
Nov 10, 2004
Messages
351
BJs are slower, and most of them just point out to another function. That's why UnitDamageTarget is better than UnitDamageTargetBJ. UnitDamageTargetBJ just points out to UnitDamageTarget.

The reason why you get an error is because WE requires that there's a return just over endfunction. Your return is inside an if, so it is not at the bottom.

And yes, i think it is MUI as it doesn't use waits or anything.

Also, it DOES leak. No locations are removed. Locations aren't neccesary in jass anyways.

Read through some more tutorials and keep the spirit up, then you'll learn jass 100% in no time.
 
Level 40
Joined
Dec 14, 2005
Messages
10,532
What are the differences between these two functions ?? Just the name ???
UnitDamageTargetBJ runs UnitDamageTarget with some parameter changes, thus it's less efficient/versatile.

So, to replace BJs, look up the native they call, and try to sub in the params.

Eg:

JASS:
call UnitDamageTargetBJ( u, t, 500, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_NORMAL )

//look up the function

function UnitDamageTargetBJ takes unit whichUnit, unit target, real amount, attacktype whichAttack, damagetype whichDamage returns boolean
    return UnitDamageTarget(whichUnit, target, amount, true, false, whichAttack, whichDamage, WEAPON_TYPE_WHOKNOWS)
endfunction

//sub in the values

call UnitDamageTarget( u, t, 500, true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_NORMAL, null )

//note: WEAPON_TYPE_WHOKNOWS does the same thing as null
 
Spell Improved:

JASS:
///Here is the main condition
function Conditions takes nothing returns boolean
    return GetSpellAbilityId() == 'A00B'
endfunction
//Here is the condition that says that the level of the ability being cast is equal to 1
function Actions takes nothing returns boolean
     local unit Caster = GetTriggerUnit()
     local unit Target_Unit = GetSpellTargetUnit()
     local real SpeedBlast_Stats = I2R(GetHeroAgi(Caster, true))
     local real SpeedBlast_Damage = ( SpeedBlast_Stats + ( 0.20 * GetUnitStateSwap(UNIT_STATE_LIFE, Target_Unit) ) )
     local location Position_Target = GetUnitLoc(Target_Unit)
if GetUnitAbilityLevelSwapped('A00B', Caster) == 1 then
        call UnitDamageTarget(Caster, Target_Unit, SpeedBlast_Damage, true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_NORMAL, null)
        call CreateTextTagLocBJ( R2S(SpeedBlast_Damage), Position_Target, 0, 10, 100, 0.00, 100.00, 0 )
        call SetTextTagVelocityBJ( GetLastCreatedTextTag(), 50.00, 90 )
        call SetTextTagLifespanBJ( GetLastCreatedTextTag(), 2.00 )
        call SetTextTagPermanentBJ( GetLastCreatedTextTag(), false )
        set Target_Unit = null
        set Caster = null 
        set Position_Target = null
endif
return true
endfunction
// the trigger stuff
function InitTrig_trigger takes nothing returns nothing
local trigger Blast = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ( Blast, EVENT_PLAYER_UNIT_SPELL_EFFECT)
call TriggerAddCondition(Blast, Condition(function Conditions))
call TriggerAddAction(Blast, function Actions) 
endfunction

Thx for you replly diablo-dk and purplePoot, you are being a great help for me.

I am almost done.
The JassCraft points no errors (which is good), however i want to make my spell 100% efficient. This means that i will have to remove the BJ functions and that it must be leak free.
Trying to remove all possible leaks i create a hole new bunch of variables and nullified them in the end. Real variables don't need to be nullified so i didn't nullify them.

However i have a few problems still:
1-
JASS:
takes unit whichUnit, widget target, real amount, boolean attack, boolean ranged, attacktype attackType, damagetype damageType, weapontype weaponType returns boolean
This is the script for the UnitDamageTarget native. However i know nothing !!!
i can only do:
JASS:
takes unit Caster, Target_Unit, MindBlast_Damage, boolean attack (what is this ?? tru maybe), boolean ranged(what is this?? true ?? and what if my hero is melle ? false?), ATTACK_TYPE_NORMAL, DAMAGE_TYPE_NORMAL, null returns boolean
can you please tell me what i have to put in the other blank sections ??

2 - and my second problem is to create a variable for my floating text:
JASS:
 local handle (What do i type now?) = (ermmmm this is not like the unit local or the location local, so i make no idea what to put here as well)

These are my main problems for now ... Another thing is, what JASS tutorials do you advice me to read ??? i have already read most of the JASS tutorials this site has ... i am trying to read some new ones made by Vexorian at w3campaigns, but those are not useful ... they just bombard your mind with advanced theoretical knowledge and they don't show you how to use it ...

Thx to the mods help the real last problem i have is with leaks and the floating text =S, hope i finish it soon
Do you know where i can find a good tutorial about handlers ? i serached but i found nothing ... =( perhaps you know some.

I am open minded to new ideas ... Btw, is the leaking problem fixed now ??? If not, how can i fix it ?

Please help, nearly in the end (i think, at least until i discover how to set up all the other natives) Flame_Phoenix
 
Last edited:
1. Simple:
JASS:
native UnitDamageTarget             takes unit whichUnit, widget target, real amount, boolean attack, boolean ranged, attacktype attackType, damagetype damageType, weapontype weaponType returns boolean

WhichUnit = The unit that does the damage.
Target = The item/unit/destructable that will be damaged.
Amount = The amount of damage the whichunit will give.
Boolean Attack = I forgot what this does, but I know that you must put true for this.
Boolean Ranged = Just put false, this tells whether or not the attack is ranged.
Attacktype = This is the attack type the whichUnit will use. If you want a regular damage, just use :
JASS:
ATTACK_TYPE_NORMAL
DamageType = This is pretty much like the attacktype, I forgot what this field does. I believe this is for any buffs and effects on the target. Just use by default:
JASS:
DAMAGE_TYPE_NORMAL
WeaponType = This is for the noises I believe. So if you use an actual option for the field, it will make that noise. I suggest using this:
JASS:
WEAPON_TYPE_WHOKNOWS

2.
JASS:
type texttag            extends     handle

Use this for floating texts, so you should do this:
JASS:
local texttag NAME = CreateTextTag()

Then, you should use the other texttag functions to specify the options. Look them up in JASSCraft.

3. Daelin's tutorial is fantastic, and look at wyrmlord's tutorial too:
[Tutorial] JASS: GUI to JASS

4. Look at some of KaTTaNa's tutorials:
Using Timers and Handle Vars
Using the Handle Vars

I hope this helps!
 
Thx PurgeandFire111 for your comments and suggestions, the daelin tutorial you point is not new for me, this website also has the same tutorial, however thx for pointing those handlers and JASS tutorials.
I would like a more basic handlers tutorial if you know any ... as i already said , this is just my first JASS spell.

Also the constant function Dealin suggest doesn't work at all in my spell ...
JASS:
constant function Condition takes nothing return integer
return 'AHtb'
does not work as the WE does not recognizes my spell !!
Therefore i am forced to use the:
JASS:
function Condition takes nothing return boolean
return GetSpellAbilityId() = 'AHtb'

i would like some suggestions as well.

Also thx for you textag comments =) there are really helpful.

To PurplePoot thx for telling me what ranged booleans are. Now i understand what this stuff makes =)

I will soon post my spell here. But i still don't know if it is leak free. Please tell me if the memory leaks =S, as i need to know it.

Spell improvement:

JASS:
//Here is the main condition
function Conditions takes nothing returns boolean
    return GetSpellAbilityId() == 'AHtb'
endfunction
//Here is the condition that says that the level of the ability being cast is equal to 1
function Actions takes nothing returns boolean
     local unit Caster = GetTriggerUnit()
     local unit Target_Unit = GetSpellTargetUnit()
     local real SpeedBlast_Stats = I2R(GetHeroAgi(Caster, true))
     local real SpeedBlast_Damage = ( SpeedBlast_Stats + ( 0.20 * GetUnitStateSwap(UNIT_STATE_LIFE, Target_Unit) ) )
     local location Position_Target = GetUnitLoc(Target_Unit)
     local texttag Damage_Taked = CreateTextTagUnitBJ(R2S(SpeedBlast_Damage + 100), Target_Unit, 0, 10, 100, 0.00, 0.00, 0) 
if GetUnitAbilityLevelSwapped('AHtb', Caster) == 1 then
        call UnitDamageTarget(Caster, Target_Unit, SpeedBlast_Damage, true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_NORMAL, null)
        call SetTextTagPermanent(Damage_Taked, false)
        call SetTextTagVelocityBJ(Damage_Taked, 50.00, 90.00)
        call TriggerSleepAction(2.00)
        call DestroyTextTag(Damage_Taked)
        set Damage_Taked = null
        set Target_Unit = null
        set Caster = null 
        set Position_Target = null
endif
return true
endfunction
// the trigger stuff
function InitTrig_Blast takes nothing returns nothing
local trigger Blast = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ( Blast, EVENT_PLAYER_UNIT_SPELL_EFFECT)
call TriggerAddCondition(Blast, Condition(function Conditions))
call TriggerAddAction(Blast, function Actions) 
endfunction

Guys these are the changes i made. I used a wait time to destroy and than nullify then floating text. However i still have 1 BJ function which i want to remove, but i don't know how =S.
Here it is:

Native function:
JASS:
call SetTextTagVelocity(Damage_Taked, 50.00 *Cos([What do i put here?] * bj_DEGTORAD), 90.00 *Sin([What do i put here?] * bj_DEGTORAD))

BJ correspondent:
JASS:
SetTextTagVelocityBJ(Damage_Taked, 50.00, 90.00)

Please tell me what i most put into the blank areas ... the native says:
JASS:
texttag t, real xvel, real yvel

and what i can do is:
JASS:
call SetTextTagVelocity(Damage_Taked, 50.00 *Cos([What do i put here?] * bj_DEGTORAD), 90.00 *Sin([What do i put here?] * bj_DEGTORAD))

Can some1 please tell me if this is well made ???
I tested my spell and i think it is MUI. Thx to all who helped. Now i want it to be 100% efficient - leak free and no BJ's. Help please ?
 
Last edited:
Level 40
Joined
Dec 14, 2005
Messages
10,532
You forgot to call RemoveLocation(Position_Target) before setting it to null, but that doesn't matter, because we'll be removing Position_Target completely, since you don't use it - remove local location Position_Target = GetUnitLoc(Target_Unit) and set Position_Target = null

Hmm, no bjs, eh?

Replace if GetUnitAbilityLevelSwapped('AHtb', Caster) == 1 then with if GetUnitAbilityLevel(Caster,'AHtb') == 1 then

Next, the texttag, this is a bit harder. Replace local texttag Damage_Taked = CreateTextTagUnitBJ(R2S(SpeedBlast_Damage + 100), Target_Unit, 0, 10, 100, 0.00, 0.00, 0) with

JASS:
    local texttag Damage_Taked = CreateTextTag()
    call SetTextTagText( Damage_Taked, R2S(SpeedBlast_Damage+100), .023 )
    call SetTextTagPosUnit( Damage_Taked, Target_Unit, 0 )
    call SetTextTagColor( Damage_Taked, 255, 0, 0, 255 )

Next, replace call SetTextTagVelocityBJ(Damage_Taked, 50.00, 90.00) with call SetTextTagVelocity( Damage_Taked, .0277, 0 )

Next, scrap the if-statement, change function Actions takes nothing returns boolean to function Actions takes nothing returns nothing. You must also remove return true

Now, removing if GetUnitAbilityLevel(Caster,'AHtb') == 1 then and endif, modify the condition's line return GetSpellAbilityId() == 'AHtb' to be return GetSpellAbilityId() == 'AHtb' and GetUnitAbilityLevel( GetTriggerUnit(), 'AHtb' ) == 1

Next,

JASS:
local real SpeedBlast_Stats = I2R(GetHeroAgi(Caster, true))  local real SpeedBlast_Damage = ( SpeedBlast_Stats + ( 0.20 * GetUnitStateSwap(UNIT_STATE_LIFE, Target_Unit) ) )

becomes local real SpeedBlast_Damage = GetHeroAgi( Caster, true ) + .2*GetWidgetLife(Target_Unit)

Finally, rename your functions from "Conditions' and 'Actions' to '(name of spell)_Conditions' and '(name of spell)_Actions', or something, to avoid conflicts between multiple triggers.
 
Thx purplePoot. When i studied your post i learned lots of stuff, however there are also things that i was unable to understand.

Where does the Getwidget native come from ??
How did you calculate the xvel and the yvel ???

Well, these are the most important for now. Anyway here is my updated spell.

JASS:
//Here is the main condition
function SpeedBlast_Conditions takes nothing returns boolean
    return GetSpellAbilityId() == 'AHtb' and GetUnitAbilityLevel( GetTriggerUnit(), 'AHtb' ) == 1
endfunction
//Here is the condition that says that the level of the ability being cast is equal to 1
function SpeedBlast_Actions takes nothing returns nothing
    local unit Caster = GetTriggerUnit()
    local unit Target_Unit = GetSpellTargetUnit()
    local real SpeedBlast_Damage = ( GetHeroAgi( Caster, true ) + ( 0.20 * GetWidgetLife(Target_Unit) ) )
    local texttag Damage_Taked = CreateTextTag()
    call SetTextTagText(Damage_Taked, R2S(SpeedBlast_Damage+100), .023 )
    call SetTextTagPosUnit( Damage_Taked, Target_Unit, 0 )
    call SetTextTagColor( Damage_Taked, 255, 0, 0, 255 )   
    call UnitDamageTarget(Caster, Target_Unit, SpeedBlast_Damage, true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_NORMAL, null)
    call SetTextTagPermanent(Damage_Taked, false)
    call SetTextTagVelocity( Damage_Taked, 0, .0277 )
    call TriggerSleepAction(2.00)
    call DestroyTextTag(Damage_Taked)
    set Damage_Taked = null
    set Target_Unit = null
    set Caster = null 
endfunction
// the trigger stuff
function InitTrig_SpeedBlast takes nothing returns nothing
local trigger SpeedBlast = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ( SpeedBlast, EVENT_PLAYER_UNIT_SPELL_EFFECT)
call TriggerAddCondition(SpeedBlast, Condition(function SpeedBlast_Conditions))
call TriggerAddAction(SpeedBlast, function SpeedBlast_Actions) 
endfunction

As you can see, worked hard to understand and to do everything you suggested. I think the spell is ok for now.

1 last question remains, i would like to transform this spell into a 3 level spell.
I know i can do it by constant methods but i don't want that. The values i have in mind are no constant and there is no connection or formula for them.

So what do i need to do to make this spell, a 3 levels spell ???
Do i have to create an unique individual trigger for each level ?

I also don't want to abuse of your good will, truly appreciate all the help you and the other people gave to me, however i must ask you if you can think of any solution for this spell of mine http://www.hiveworkshop.com/forums/showthread.php?t=38512

WyrmLord already tried to help me but he was unable to do so, because he also doesn't know what do to .. please i ask for all those who understand about AoE spells to help out with this 1.
 
Level 40
Joined
Dec 14, 2005
Messages
10,532
To make it a 3-level spell, first remove the part of the condition that checks if it's level one - remove this: and GetUnitAbilityLevel( GetTriggerUnit(), 'AHtb' ) == 1

Then, just apply a modifier to your spell. Let's say you want your spell to do 150/200/250 damage (depending on the level)

Then, the damage would be

100 + 50*level

So, in your case, let's say we do .20/.30/.40 of the target's life as the modifier, we would have

JASS:
local real SpeedBlast_Damage = GetHeroAgi( Caster, true ) + ( (.1 + .1*GetUnitAbilityLevel(Caster,'AHtb')) * GetWidgetLife(Target_Unit) )

And GetWidgetLife(someUnit) is the equivelant of GetUnitState(someUnit,UNIT_STATE_LIFE). There's also a SetWidgetLife. That's just one of those things you have to pick up and learn by experience, and there's no good way to find out. (it saves code space/is faster to write, and I *think* it runs a bit faster too)
 
I am confused, according to your formula, the damage of my spell should be:
JASS:
local real SpeedBlast_Damage = GetHeroAgi( Caster, true ) + ( (100 + 50*GetUnitAbilityLevel(Caster,'AHtb')) * ((0.1*GetUnitAbilityLevel(Caster,'AHtb'))*GetWidgetLife(Target_Unit) )

This means that the damage caused will be the agility of the hero + 100 damage (1st level) and + 20% of targets current hp(1st level).

Rit ??

Besides, imagine that i have, a storm bolt ability (per example) and i want it to do 100, 110, 175 damage to an enemy unit. Because there is no constant between these values, it means that i have to create a separate trigger for them ?
 
thx for replly, but you still don't answer my question:

flame_phoenix said:
Besides, imagine that i have, a storm bolt ability (per example) and i want it to do 100, 110, 436 damage to an enemy unit. Because there is no constant between these values, it means that i have to create a separate trigger for them ?

i understand that you must be tired of posting so many posts and help every1 (me included, i know i can be boring =s ). but plz answer correctly.

I decided also that i will give you credit on my map, special thanks section (there are only 2 people there and now with you 3, it is in fact a very special thanks section that will appear in the loading screen) because you are the moderator (nearly the only one) who is helping me, and i don't forget who helps me.
 
Level 7
Joined
Jun 10, 2007
Messages
225
No need to do seperate triggers. Instead, just, when you deal the damage, do something like:
JASS:
if Level == 1 then
    <deal 100 damage>
elseif Level == 2 then
    <deal 110 damage>
elseif Level == 3 then
    <deal 436 damage>
endif
 
Like this ????

JASS:
//Here is the main condition
function SpeedBlast_Conditions takes nothing returns boolean
    return GetSpellAbilityId() == 'AHtb'
endfunction
//Here is the condition that says that the level of the ability being cast is equal to 1
function SpeedBlast_Actions takes nothing returns nothing
    if GetUnitAbilityLevel( GetTriggerUnit(), 'AHtb' ) == 1 then
    local unit Caster = GetTriggerUnit()
    local unit Target_Unit = GetSpellTargetUnit()
    local real SpeedBlast_Damage = ( GetHeroAgi( Caster, true ) + ( 0.20 * GetWidgetLife(Target_Unit) ) )
    local texttag Damage_Taked = CreateTextTag()
    call SetTextTagText(Damage_Taked, R2S(SpeedBlast_Damage+100), .023 )
    call SetTextTagPosUnit( Damage_Taked, Target_Unit, 0 )
    call SetTextTagColor( Damage_Taked, 255, 0, 0, 255 )   
    call UnitDamageTarget(Caster, Target_Unit, SpeedBlast_Damage, true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_NORMAL, null)
    call SetTextTagPermanent(Damage_Taked, false)
    call SetTextTagVelocity( Damage_Taked, 0, .0277 )
    call TriggerSleepAction(2.00)
    call DestroyTextTag(Damage_Taked)
    set Damage_Taked = null
    set Target_Unit = null
    set Caster = null  
    elseif GetUnitAbilityLevel( GetTriggerUnit(), 'AHtb' ) == 2 then
    local unit Caster = GetTriggerUnit()
    local unit Target_Unit = GetSpellTargetUnit()
    local real SpeedBlast_Damage = ( GetHeroAgi( Caster, true ) + ( 0.20 * GetWidgetLife(Target_Unit) ) )
    local texttag Damage_Taked = CreateTextTag()
    call SetTextTagText(Damage_Taked, R2S(SpeedBlast_Damage+100), .023 )
    call SetTextTagPosUnit( Damage_Taked, Target_Unit, 0 )
    call SetTextTagColor( Damage_Taked, 255, 0, 0, 255 )   
    call UnitDamageTarget(Caster, Target_Unit, SpeedBlast_Damage, true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_NORMAL, null)
    call SetTextTagPermanent(Damage_Taked, false)
    call SetTextTagVelocity( Damage_Taked, 0, .0277 )
    call TriggerSleepAction(2.00)
    call DestroyTextTag(Damage_Taked)
    set Damage_Taked = null
    set Target_Unit = null
    set Caster = null
    elseif GetUnitAbilityLevel( GetTriggerUnit(), 'AHtb' ) == 3 then
    local unit Caster = GetTriggerUnit()
    local unit Target_Unit = GetSpellTargetUnit()
    local real SpeedBlast_Damage = ( GetHeroAgi( Caster, true ) + ( 0.20 * GetWidgetLife(Target_Unit) ) )
    local texttag Damage_Taked = CreateTextTag()
    call SetTextTagText(Damage_Taked, R2S(SpeedBlast_Damage+100), .023 )
    call SetTextTagPosUnit( Damage_Taked, Target_Unit, 0 )
    call SetTextTagColor( Damage_Taked, 255, 0, 0, 255 )   
    call UnitDamageTarget(Caster, Target_Unit, SpeedBlast_Damage, true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_NORMAL, null)
    call SetTextTagPermanent(Damage_Taked, false)
    call SetTextTagVelocity( Damage_Taked, 0, .0277 )
    call TriggerSleepAction(2.00)
    call DestroyTextTag(Damage_Taked)
    set Damage_Taked = null
    set Target_Unit = null
    set Caster = null
    endif
endfunction
// the trigger stuff
function InitTrig_SpeedBlast takes nothing returns nothing
local trigger SpeedBlast = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ( SpeedBlast, EVENT_PLAYER_UNIT_SPELL_EFFECT)
call TriggerAddCondition(SpeedBlast, Condition(function SpeedBlast_Conditions))
call TriggerAddAction(SpeedBlast, function SpeedBlast_Actions) 
endfunction
 
Level 40
Joined
Dec 14, 2005
Messages
10,532
No, you can't define locals anywhere in the script anyways.

Like this;

JASS:
//other locals
local real SpeedBlast_Damage
if GetUnitAbilityLevel(Caster,'AHtb') == 1 then
    set SpeedBlast_Damage = <damage>
elseif GetUnitAbilityLevel(Caster,'AHtb') == 2 then
    set SpeedBlast_Damage = <damage>
elseif GetUnitAbilityLevel(Caster,'AHtb') == 3 then
    set SpeedBlast_Damage = <damage>
endif
//make the texttag and do the damage, etc, etc
 
Thx purplepoot

Final spell version:

JASS:
//Here is the main condition
function SpeedBlast_Conditions takes nothing returns boolean
    return GetSpellAbilityId() == 'AHtb' 
endfunction
//Here is the condition that says that the level of the ability being cast is equal to 1
function SpeedBlast_Actions takes nothing returns nothing
    local unit Caster = GetTriggerUnit()
    local unit Target_Unit = GetSpellTargetUnit()
    local real SpeedBlast_Damage
    local texttag Damage_Taked = CreateTextTag()
    if GetUnitAbilityLevel( GetTriggerUnit(), 'AHtb' ) == 1 then 
    set SpeedBlast_Damage = ( GetHeroAgi( Caster, true ) + (25 + 0.10 * GetWidgetLife(Target_Unit) ) )
    elseif GetUnitAbilityLevel( GetTriggerUnit(), 'AHtb' ) == 2 then
    set SpeedBlast_Damage = ( GetHeroAgi( Caster, true ) + ( 50 + 0.20 * GetWidgetLife(Target_Unit) ) )
    elseif GetUnitAbilityLevel( GetTriggerUnit(), 'AHtb' ) == 3 then
    set SpeedBlast_Damage = ( GetHeroAgi( Caster, true ) + (75 + 0.30 * GetWidgetLife(Target_Unit) ) ) 
    endif 
    call SetTextTagText(Damage_Taked, R2S(SpeedBlast_Damage), .023 )   
    call SetTextTagPosUnit( Damage_Taked, Target_Unit, 0 )
    call SetTextTagColor( Damage_Taked, 255, 0, 0, 255 )   
    call UnitDamageTarget(Caster, Target_Unit, SpeedBlast_Damage, true, false, ATTACK_TYPE_CHAOS, DAMAGE_TYPE_UNIVERSAL, null)
    call SetTextTagPermanent(Damage_Taked, false)
    call SetTextTagVelocity( Damage_Taked, 0, .0277 )
    call TriggerSleepAction(2.00)
    call DestroyTextTag(Damage_Taked)
    set Damage_Taked = null
    set Target_Unit = null
    set Caster = null 
endfunction
// the trigger stuff
function InitTrig_SpeedBlast takes nothing returns nothing
local trigger SpeedBlast = CreateTrigger()
call TriggerRegisterAnyUnitEventBJ( SpeedBlast, EVENT_PLAYER_UNIT_SPELL_EFFECT)
call TriggerAddCondition(SpeedBlast, Condition(function SpeedBlast_Conditions))
call TriggerAddAction(SpeedBlast, function SpeedBlast_Actions) 
endfunction

Special Thanks:
-Purplepoot
- other people who helped me

Btw, which JASS program do you advice me to use ?? my program is to old ... can you please tell me a new recent JASS program that is good ?
 
Level 40
Joined
Dec 14, 2005
Messages
10,532
JassCraft

Or, you can use the JassNewGenPack World Editor, it adds vJass (all the structs and stuff you always hear about), plus a syntax checker that doesn't crash on half the errors, and gives proper errors on the rest.

Oh, and in this case, your damage is actually constant per level your spell deals;

GetHeroAgi( Caster, true ) + (25 * GetHeroAbilityLevel(Caster,'AHtb') + 0.10 * GetHeroAbilityLevel(Caster,'AHtb') * GetWidgetLife(Target_Unit) )

damage. Thus, you can revert to the old method of setting the variable (just do it upon the local's initialization), and remove all the if-statements
 
Status
Not open for further replies.
Top