• 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] Multi-instance spell problem

Status
Not open for further replies.
Level 5
Joined
Aug 3, 2005
Messages
150
Hi, I want to make a spell that casts an immolation on any unit and damages all nearby units over time. I've started using jass so I could use local variables, since at one of the levels the duration of the spell will be higher than the cooldown. The problem is that it only half works, both instances of the spell work for a few seconds then both finish at the same time (earlier than at least one of them should).

Code:
function Trig_SET_ON_FIRE_Actions takes nothing returns nothing
    local integer Level_SETONFIRE
    local unit Target_SETONFIRE
    local unit Caster_SETONFIRE
    set Level_SETONFIRE = GetUnitAbilityLevelSwapped('A000', GetSpellAbilityUnit())
    set Target_SETONFIRE = GetSpellTargetUnit()
    set Caster_SETONFIRE = GetSpellAbilityUnit()
    set bj_forLoopAIndex = 1
    set bj_forLoopAIndexEnd = ( 6 + ( 2 * Level_SETONFIRE ) )
    call PolledWait( 0.51 )
    loop
        exitwhen bj_forLoopAIndex > bj_forLoopAIndexEnd
        if ( GetBooleanAnd( IsUnitAliveBJ(Target_SETONFIRE), UnitHasBuffBJ(Target_SETONFIRE, 'B000') ) )then
            call UnitDamagePointLoc( Caster_SETONFIRE, 0, ( 145.00 + ( 15.00 * Level_SETONFIRE ) ), GetUnitLoc(Target_SETONFIRE), (6 + (5 * Level_SETONFIRE) ), ATTACK_TYPE_NORMAL, DAMAGE_TYPE_NORMAL )
            call PolledWait( 1.00 )
        else
            call DoNothing(  )
            set bj_forLoopAIndex = bj_forLoopAIndexEnd + 1
        endif
        set bj_forLoopAIndex = bj_forLoopAIndex + 1
    endloop
endfunction
Level_SETONFIRE = Level of the ability
Target_SETONFIRE = Target of the ability
Caster_SETONFIRE = Caster of the ability
Wait before loop for animation and buff purposes (this is fine tuned)
Loop: Damages area near target, waits 1 second, repeat if target isn't dead or has removed buff

edit: note that it works perfectly fine if i have just one instance of the spell running at a time
 
Level 27
Joined
Feb 22, 2006
Messages
3,052
Ick. BJ calls and ForLoopA's.
A few things:
You no longer need to have ForLoopA's
Instead, do

JASS:
function Trig_SET_ON_FIRE_Actions takes nothing returns nothing
    local integer i
    local integer Level_SETONFIRE
    local unit Target_SETONFIRE
    local unit Caster_SETONFIRE
    set Level_SETONFIRE = GetUnitAbilityLevelSwapped('A000', GetSpellAbilityUnit())
    set Target_SETONFIRE = GetSpellTargetUnit()
    set Caster_SETONFIRE = GetSpellAbilityUnit()
    call PolledWait( 0.51 )
loop
        exitwhen i = ( 6 + ( 2 * Level_SETONFIRE ) )
        if ( GetBooleanAnd( IsUnitAliveBJ(Target_SETONFIRE), UnitHasBuffBJ(Target_SETONFIRE, 'B000') ) )then
            call UnitDamagePointLoc( Caster_SETONFIRE, 0, ( 145.00 + ( 15.00 * Level_SETONFIRE ) ), GetUnitLoc(Target_SETONFIRE), (6 + (5 * Level_SETONFIRE) ), ATTACK_TYPE_NORMAL, DAMAGE_TYPE_NORMAL )
            call PolledWait( 1.00 )
        else
            set i = i + 1
        endif
        set i = i + 1
    endloop
endfunction

Also, use [code=jass][/code] Tags like I did.
Third, get rid of the call DoNothing( )'s. Don't need those.
Fourth, get those BJ calls out of your code.
As for the non-MUI, I'm not sure. It could be because you used ForLoopA, I'm not 100% sure though.
--donut3.5--
 
Level 5
Joined
Aug 3, 2005
Messages
150
Fixing the loop worked like a charm. With some minor fixes, all is well, thanks!
JASS:
function Trig_SET_ON_FIRE_Actions takes nothing returns nothing
    local integer Level_SETONFIRE
    local unit Target_SETONFIRE
    local unit Caster_SETONFIRE
    local integer i
    set Level_SETONFIRE = GetUnitAbilityLevelSwapped('A000', GetSpellAbilityUnit())
    set Target_SETONFIRE = GetSpellTargetUnit()
    set Caster_SETONFIRE = GetSpellAbilityUnit()
    set i = 0
    call PolledWait( 0.51 )
    loop
        exitwhen i >= (6 + ( 2 * Level_SETONFIRE ) )
        if ( GetBooleanAnd( IsUnitAliveBJ(Target_SETONFIRE), UnitHasBuffBJ(Target_SETONFIRE, 'B000') ) )then
            call UnitDamagePointLoc( Caster_SETONFIRE, 0, ( 145.00 + ( 15.00 * Level_SETONFIRE ) ), GetUnitLoc(Target_SETONFIRE), (6 + (5 * Level_SETONFIRE) ), ATTACK_TYPE_NORMAL, DAMAGE_TYPE_NORMAL )
            call PolledWait( 1.00 )
        else
            set i = (6 + ( 2 * Level_SETONFIRE ) )
        endif
        set i = i + 1
    endloop
endfunction
Also am I supposed to find an alternative to the BJs in the loop conditions? How do I go about doing that? I'm learning this the "convert to custom text" way =/
 
Level 20
Joined
Apr 22, 2007
Messages
1,960
You can also directly initialize local variables. E.G:

JASS:
local integer Level_SETONFIRE
local unit Target_SETONFIRE
local unit Caster_SETONFIRE
local integer i
set Level_SETONFIRE = GetUnitAbilityLevelSwapped('A000', GetSpellAbilityUnit())
set Target_SETONFIRE = GetSpellTargetUnit()
set Caster_SETONFIRE = GetSpellAbilityUnit()
set i = 0

Can be changed to this:
JASS:
local unit Caster_SETONFIRE=GetSpellAbilityUnit()
local integer Level_SETONFIRE=GetUnitAbilityLevelSwapped('A000', Caster_SETONFIRE)
local unit Target_SETONFIRE=GetSpellTargetUnit()
local integer i=0

You may also have noticed that I moved Caster_SETONFIRE above Level_SETONFIRE because you called GetSpellAbilityUnit() twice. This way, I can refer to the local which I just initialized, which makes the code faster than calling loads of functions. Remember, if you ever call functions that return values more than once, store them into a local and then refer to the local. Your script will be more efficient. :thumbs_up:
 
Status
Not open for further replies.
Top