• 🏆 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!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

[JASS] Spell Help Plz!

Status
Not open for further replies.
Level 2
Joined
Oct 17, 2008
Messages
11
ignore bumps, i was using that to test how far my spell got, iv goten it all the way but it compleatly lags the hell out of my computer so im not sure if thats because of the amount of times it goes threw the function also im not sure if my gethandleunits/sethandlehandles are working properly because im stiff iffy on if i set up the game cache corectly
suggestions please
JASS:
function Wraiths_burn takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local unit caster = GetHandleUnit(t, "wraithcaster")
    local group wards = GetHandleGroup(t, "dwards")
    local unit ward 
    local effect spelleff
    call DisplayTextToPlayer(Player(0),0,0,"Bump1")
    set spelleff = AddSpecialEffect("Abilities\\Spells\\Human\\FlameStrike\\FlameStrike1.mdl",GetUnitX(caster),GetUnitY(caster))
    call DisplayTextToPlayer(Player(0),0,0,"Bump2") 
    call DestroyEffect(spelleff)
    call DisplayTextToPlayer(Player(0),0,0,"Bump3")        
    call UnitDamagePoint(caster,1.3,200,GetUnitX(caster),GetUnitY(caster),50,true, false, (ATTACK_TYPE_MAGIC), (DAMAGE_TYPE_FIRE),null) 
        call DisplayTextToPlayer(Player(0),0,0,"Bump4")
        loop                                                             
            set ward = FirstOfGroup(wards)                            
            exitwhen wards == null       
            call DisplayTextToPlayer(Player(0),0,0,"Bump5")                           
                set spelleff = AddSpecialEffect("Abilities\\Spells\\Human\\FlameStrike\\FlameStrike1.mdl",GetUnitX(ward),GetUnitY(ward)) 
                call DisplayTextToPlayer(Player(0),0,0,"Bump6")
                call DestroyEffect(spelleff)                                                          
                call DisplayTextToPlayer(Player(0),0,0,"Bump7")
                call UnitDamagePoint(caster,1.3,200,GetUnitX(ward),GetUnitY(ward),50,true, false, (ATTACK_TYPE_MAGIC), (DAMAGE_TYPE_FIRE),null)  
                call DisplayTextToPlayer(Player(0),0,0,"Bump8")
                call GroupRemoveUnit(wards,ward)       
        endloop
endfunction
//=============================//
function WardCheck takes nothing returns boolean
     local unit ward = GetFilterUnit()
     return GetUnitTypeId(ward) == 'o001' 
endfunction
//=============================//
function Execute_Wraiths_Burn takes nothing returns nothing
    local unit wraithcaster = GetTriggerUnit()
    local ability Wraith_Burn
    local group dwards
    local timer t = CreateTimer()
    local real i
    local integer spell_level
    local filterfunc WardC = Filter(function WardCheck)
    set dwards = GetUnitsInRangeOfLocMatching(1000,GetUnitLoc(wraithcaster), WardC) 
    if ( GetSpellAbilityId()=='A013') then
    call DisplayTextToPlayer(GetOwningPlayer(wraithcaster),0,0,"Bump1")
        set spell_level = GetUnitAbilityLevel(wraithcaster,'A013')
        call DisplayTextToPlayer(GetOwningPlayer(wraithcaster),0,0,"Bump2") 
        if( spell_level == 1 ) then
        call DisplayTextToPlayer(GetOwningPlayer(wraithcaster),0,0,"Bump3")
            call SetHandleHandle(t, "wraithcaster", wraithcaster)
            call SetHandleHandle(t, "dwards", dwards)
            set i = 1.6
            call TimerStart(t,i,true, function Wraiths_burn)    
        elseif( spell_level == 2 ) then
        call DisplayTextToPlayer(GetOwningPlayer(wraithcaster),0,0,"Bump4")
            call SetHandleHandle(t, "wraithcaster", wraithcaster)
            call SetHandleHandle(t, "dwards", dwards)
            set i = 1.3
            call TimerStart(t,i,true, function Wraiths_burn) 
        elseif( spell_level == 3 ) then
        call DisplayTextToPlayer(GetOwningPlayer(wraithcaster),0,0,"Bump5")
            call SetHandleHandle(t, "wraithcaster", wraithcaster)
            call SetHandleHandle(t, "dwards", dwards)
            call DisplayTextToPlayer(GetOwningPlayer(wraithcaster),0,0,"Bump6")
            set i = 1
            call TimerStart(t,i,true, function Wraiths_burn)
            call DisplayTextToPlayer(GetOwningPlayer(wraithcaster),0,0,"Bump7")
        endif
    endif
call TriggerSleepAction(8+spell_level*2)
call FlushHandleLocals(t)
call DestroyTimer(t)
endfunction

//===========================================================================
function InitTrig_Wraiths_Burn takes nothing returns nothing
    set gg_trg_Wraiths_Burn = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_Wraiths_Burn, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddAction( gg_trg_Wraiths_Burn, function Execute_Wraiths_Burn )
endfunction
 
Level 2
Joined
Oct 17, 2008
Messages
11
thanks but im still new to jass and im not sure what TSA or LHV stand for
but iv been working on my spell and i have it as this now, the game dosent lag and got my handels to work properly, spell works fine no lag just the problem of i damage point but i only want to damage units in the 200 radius that are enemys, and heal any units in that area that are allys
JASS:
function WardCheck takes nothing returns boolean
     local unit ward = GetFilterUnit()
     return GetUnitTypeId(ward) == 'o001' 
endfunction
//=============================//
function Wraiths_burn takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local unit caster
    local group wards
    local unit ward 
    local effect spelleff
    local filterfunc WardC = Filter(function WardCheck)
    set caster = GetHandleUnit(t,"wraithcaster") 
    set wards = GetUnitsInRangeOfLocMatching(1000,GetUnitLoc(caster), WardC)
    set spelleff = AddSpecialEffect("Abilities\\Spells\\Human\\MarkOfChaos\\MarkOfChaosTarget.mdl",GetUnitX(caster),GetUnitY(caster))
    call UnitDamagePoint(caster,0,200,GetUnitX(caster),GetUnitY(caster),50,true, false, (ATTACK_TYPE_CHAOS), (DAMAGE_TYPE_FIRE),null)
    call SetUnitState(caster, UNIT_STATE_LIFE, ((GetUnitState(caster,UNIT_STATE_LIFE))+50)) 
        loop                                                             
            set ward = FirstOfGroup(wards)                            
            exitwhen wards == null
            if ( GetUnitTypeId(ward) == 'o001' ) then                                  
                set spelleff = AddSpecialEffect("Abilities\\Spells\\Human\\MarkOfChaos\\MarkOfChaosTarget.mdl",GetUnitX(ward),GetUnitY(ward)) 
                call UnitDamagePoint(caster,0,200,GetUnitX(ward),GetUnitY(ward),50,true, false, (ATTACK_TYPE_CHAOS), (DAMAGE_TYPE_FIRE),null)
                call SetUnitState(ward, UNIT_STATE_LIFE, ((GetUnitState(ward,UNIT_STATE_LIFE))+50))
            endif  
            call GroupRemoveUnit(wards,ward)     
        endloop
endfunction
//=============================//
function Execute_Wraiths_Burn takes nothing returns nothing
    local unit wraithcaster = GetTriggerUnit()
    local ability Wraith_Burn
    local timer t = CreateTimer()
    local real i
    local integer spell_level
    if ( GetSpellAbilityId()=='A013') then
        set spell_level = GetUnitAbilityLevel(wraithcaster,'A013')
        if( spell_level == 1 ) then
            call SetHandleHandle(t, "wraithcaster", wraithcaster)
            set i = 1.9
            call TimerStart(t,i,true, function Wraiths_burn)    
        elseif( spell_level == 2 ) then
            call SetHandleHandle(t, "wraithcaster", wraithcaster)
            set i = 1.3
            call TimerStart(t,i,true, function Wraiths_burn) 
        elseif( spell_level == 3 ) then
            call SetHandleHandle(t, "wraithcaster", wraithcaster)
            set i = 1
            call TimerStart(t,i,true, function Wraiths_burn)
        endif
    endif
call TriggerSleepAction(8+spell_level*2) 
call FlushHandleLocals(t)
call DestroyTimer(t)
endfunction
//===========================================================================
function InitTrig_Wraiths_Burn takes nothing returns nothing
    set gg_trg_Wraiths_Burn = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_Wraiths_Burn, EVENT_PLAYER_UNIT_SPELL_CHANNEL )
    call TriggerAddAction( gg_trg_Wraiths_Burn, function Execute_Wraiths_Burn )
endfunction
 
Level 3
Joined
Aug 20, 2008
Messages
54
If you are using a special effect, and you do NOT have any kind of wait, you dont need to make a local and set the local as the effect, if you are destroying it right away use this:
JASS:
call DestroyEffect(AddSpecialEffect(All the info here))
This way you dont have to make a local, set the local, then null the local at the end to clean leaks.
By the way, TSA means TriggerSleepAction. Dont use them lol.

EDIT: Also, I optimized your other trigger, you may want to consider that when you use if's when there are functions that are exactly the same in multiple if's that you can compile them down to one and fit it into the right place, saves space and trigger speed.
 
Level 2
Joined
Oct 17, 2008
Messages
11
yes thanks for the help on both triggers heres my final for this one (ill fix the whole effect detroying thing tho)
show
JASS:
function Wraiths_burn takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local unit caster
    local group wards
    local unit ward 
    local effect spelleff
    local filterfunc WardC = Filter(function WardCheck)
    local unit dummy
    local effect S
    set caster = GetHandleUnit(t,"wraithcaster") 
    set wards = GetUnitsInRangeOfLocMatching(1000,GetUnitLoc(caster), WardC)
        set dummy = CreateUnit(GetOwningPlayer(caster), 'h001', GetUnitX(caster),GetUnitY(caster), 0)
        call IssueImmediateOrder(dummy, "stomp")
        call UnitApplyTimedLife(dummy, 'BTLF', 1.00)
        set S = AddSpecialEffect("war3mapImported\\NewGroundEX.mdl",GetUnitX(caster),GetUnitY(caster))
        call DestroyEffect(S)
        loop                                                            
            set ward = FirstOfGroup(wards)                            
            exitwhen wards == null
            if ( GetUnitTypeId(ward) == 'o001' ) and (GetOwningPlayer(caster)==GetOwningPlayer(ward)) then
            call IssueImmediateOrder(ward,"stomp")
            set S = AddSpecialEffect("war3mapImported\\NewGroundEX.mdl",GetUnitX(ward),GetUnitY(ward))
            call DestroyEffect(S)
            endif  
            call GroupRemoveUnit(wards,ward)     
        endloop
    set dummy = null    
    call DestroyFilter(WardC)
endfunction
//=============================//
function Execute_Wraiths_Burn takes nothing returns nothing
    local unit wraithcaster = GetTriggerUnit()
    local ability Wraith_Burn
    local timer t = CreateTimer()
    local real i
    local integer spell_level
    if ( GetSpellAbilityId()=='A013') then
        set spell_level = GetUnitAbilityLevel(wraithcaster,'A013')
        if( spell_level == 1 ) then
            call SetHandleHandle(t, "wraithcaster", wraithcaster)
            set i = 1.9
            call TimerStart(t,i,true, function Wraiths_burn)    
        elseif( spell_level == 2 ) then
            call SetHandleHandle(t, "wraithcaster", wraithcaster)
            set i = 1.3
            call TimerStart(t,i,true, function Wraiths_burn) 
        elseif( spell_level == 3 ) then
            call SetHandleHandle(t, "wraithcaster", wraithcaster)
            set i = 1
            call TimerStart(t,i,true, function Wraiths_burn)
        endif
    endif
call TriggerSleepAction(8+spell_level*2) 
call FlushHandleLocals(t)
call DestroyTimer(t)
endfunction
thanks! +rep
 
Level 3
Joined
Aug 20, 2008
Messages
54
Here I optimized your code a little.
JASS:
function Wraiths_burn takes nothing returns nothing
    local timer t = GetExpiredTimer()
    local unit caster
    local group wards
    local unit ward
    local effect spelleff
    local filterfunc WardC = Filter(function WardCheck)
    local unit dummy

    set caster = GetHandleUnit(t,"wraithcaster")
    set wards = GetUnitsInRangeOfLocMatching(1000,GetUnitLoc(caster), WardC)
    set dummy = CreateUnit(GetOwningPlayer(caster), 'h001', GetUnitX(caster),GetUnitY(caster), 0)

    call IssueImmediateOrder(dummy, "stomp")
    call UnitApplyTimedLife(dummy, 'BTLF', 1.00)
    call DestroyEffect(AddSpecialEffect("war3mapImported\\NewGroundEX.mdl",GetUnitX(caster),GetUnitY(caster)))
        loop
            set ward = FirstOfGroup(wards)
            exitwhen wards == null

            if GetUnitTypeId(ward) == 'o001' and GetOwningPlayer(caster) == GetOwningPlayer(ward) then
                call IssueImmediateOrder(ward,"stomp")
                call DestroyEffect(AddSpecialEffect("war3mapImported\\NewGroundEX.mdl",GetUnitX(ward),GetUnitY(ward)))
            endif
            call GroupRemoveUnit(wards,ward)
        endloop

    set dummy = null
    set ward = null
    set caster = null
    set spelleff = null
    call DestroyFilter(WardC)
    call DestroyGroup(wards)
endfunction
//=============================//
function Execute_Wraiths_Burn takes nothing returns nothing
    local unit wraithcaster = GetTriggerUnit()
    local ability Wraith_Burn
    local timer t = CreateTimer()
    local real i
    local integer spell_level

    if ( GetSpellAbilityId()=='A013') then
        set spell_level = GetUnitAbilityLevel(wraithcaster,'A013')
        call SetHandleHandle(t, "wraithcaster", wraithcaster)

        if( spell_level == 1 ) then
            set i = 1.9
        elseif( spell_level == 2 ) then
            set i = 1.3
        elseif( spell_level == 3 ) then
            set i = 1
        endif

        call TimerStart(t,i,true, function Wraiths_burn)
    endif
//Polled Wait is better than TSA.
call PolledWait(8+spell_level*2)
call FlushHandleLocals(t)
call DestroyTimer(t)
set wraithcaster = null
endfunction
 
Last edited:

Dr Super Good

Spell Reviewer
Level 63
Joined
Jan 18, 2005
Messages
27,197
Destroying timers I heard really is not a problem. Recycling has some uses as it avoids the annoying ghost run that perodic timers suffer from.

Generally it is good to recycle them as it avoids unnescecary executions. Personally, I perfer to have few timers that just loop lots of code for MUI. Basically, by this I mean you cluster perodic script into one timer that runs all of it once. It is quite effective for making easy MUI spells and is hardly visable if done right.

Ofcourse in this case, a more complex system would be needed but it could avoid the need for handle systems at all (much faster spell) as you would purly be looping throu items in an array.

xAbysSx, that still does not null quite a number of locals resulting in handle index leaks.
 
Level 3
Joined
Aug 20, 2008
Messages
54
Generally it is good to recycle them as it avoids unnescecary executions. Personally, I perfer to have few timers that just loop lots of code for MUI. Basically, by this I mean you cluster perodic script into one timer that runs all of it once. It is quite effective for making easy MUI spells and is hardly visable if done right.
Locals allow MUI in JASS with ease, you dont NEED a loop and/or timer to make something MUI in locals. At least its what I heard.
 
Status
Not open for further replies.
Top