HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

Spell Help

04-25-2006, 07:29 AM#1
emjlr3
trying to create a spell for someone that creates an expanding nova ring at a target oover and over as long as the target si channeling

here is what i have

Collapse JASS:
function Frost_Nova_ID takes nothing returns integer
    return 'A002' //Rawcode of hero spell
endfunction

function Frost_Nova_Damage takes integer level returns real
    return level*25. //Damage per nova
endfunction

function Frost_Nova_Area takes integer level returns real
    return 125.+(level*125.) //Total area for spell
endfunction

function Frost_Nova_Amount takes integer level returns integer
    return 2*level //Number of novas
endfunction

function Frost_Nova_Periodic takes nothing returns real
    return .5 //Speed of Timer
endfunction

function Frost_Nova_Order takes nothing returns string
    return "blizzard" //Channel string    
endfunction

function Frost_Nova_Effect takes nothing returns string
    return "Abilities\\Spells\\Undead\\FrostNova\\FrostNovaTarget.mdl" // Effect location    
endfunction

//==============

function Trig_Frost_Nova_Conditions takes nothing returns boolean
    return GetSpellAbilityId() == Frost_Nova_ID() 
endfunction

function Frost_Nova_Child2 takes real dam, real area, real xtarg, real ytarg, unit cast, integer amount returns nothing
    local real x
    local real y
    local integer i = 1 
    local real dist = 50
    local real angle = 0
    
    call BJDebugMsg("blarg!")    
       
    loop
        exitwhen dist>area            
        loop
            exitwhen i>12
            set x = xtarg + dist * Cos(angle * bj_DEGTORAD)
            set y = ytarg + dist * Sin(angle * bj_DEGTORAD)
            call DestroyEffect(AddSpecialEffect(Frost_Nova_Effect(),x,y))
            set i = i + 1
            set angle = angle + 30
        endloop
        set dist = dist + 50
        set angle = 0            
        set i = 1    
        call TriggerSleepAction(0)    
    endloop    

    set cast = null
endfunction

function Frost_Nova_Child takes nothing returns nothing
    local timer t = GetExpiredTimer()    
    local real dam = GetHandleReal(t,"dam")
    local real area = GetHandleReal(t,"area")  
    local real xtarg = GetHandleReal(t,"xtarg")
    local real ytarg = GetHandleReal(t,"ytarg")
    local unit cast = GetHandleUnit(t,"cast")  
    local integer lvl = GetHandleInt(t,"lvl")
    local integer runs = GetHandleInt(t,"runs")
    local integer amount = GetHandleInt(t,"amount")
    local real area = GetHandleReal(t,"area")    
    
    if GetUnitCurrentOrder(cast) == String2OrderIdBJ(Frost_Nova_Order()) and runs<amount then         
        call Frost_Nova_Child2(dam,area,xtarg,ytarg,cast,amount)
    else        
        call PauseTimer(t)
        call TriggerSleepAction(0)
        call FlushHandleLocals(t)
        call DestroyTimer(t)        
    endif

    call SetHandleInt(t,"runs",runs+1)
    
    set cast = null
endfunction

function Trig_Frost_Nova_Actions takes nothing returns nothing
    local trigger trig = GetTriggeringTrigger()
    local timer t = CreateTimer()
    local unit cast = GetTriggerUnit()
    local location l = GetSpellTargetLoc()
    local real xtarg = GetLocationX(l)
    local real ytarg = GetLocationY(l)
    local integer lvl = GetUnitAbilityLevel(cast,Frost_Nova_ID())
    
    call SetHandleReal(t,"dam",Frost_Nova_Damage(lvl))
    call SetHandleReal(t,"area",Frost_Nova_Area(lvl))
    call SetHandleHandle(t,"cast",cast)
    call SetHandleInt(t,"lvl",lvl)
    call SetHandleReal(t,"xtarg",xtarg)
    call SetHandleReal(t,"ytarg",ytarg)
    call SetHandleInt(t,"runs",0)
    call SetHandleInt(t,"amount",Frost_Nova_Amount(lvl))
    call SetHandleReal(t,"area",Frost_Nova_Area(lvl))
    call TimerStart(t,Frost_Nova_Periodic(),true,function Frost_Nova_Child)    
    
    set cast = null    
endfunction

//===========================================================================
function InitTrig_Frost_Nova takes nothing returns nothing
    set gg_trg_Frost_Nova = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_Frost_Nova, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddCondition( gg_trg_Frost_Nova, Condition( function Trig_Frost_Nova_Conditions ) )
    call TriggerAddAction( gg_trg_Frost_Nova, function Trig_Frost_Nova_Actions )    
endfunction

granted its not, done but i am having the problem that each timer function run overrides the last call I made in the previous one, thus i only get 1 ring on each nova, and Im not sure how to go about using ExecuteFunc to get what I want, any ideas?
04-25-2006, 07:55 AM#2
PipeDream
I am not sure what your problem is from your description. One problem with your code is the use of triggersleepaction in a timer callback. In order to do this you need to spawn a new thread, otherwise the thread will go into a coma.
Collapse JASS:
function NewTimerCallback takes nothing returns nothing
    call ExecuteFunc("Frost_Nova_Child")
endfunction
Is this what you meant by needing ExecuteFunc?
04-28-2006, 12:38 AM#3
knutz
So what is it you're trying to do with Frost_Nova_Child2?

If you're trying to instantly create rings of FrostNova -50 apart till the area is covered, then these questions apply:
- Why 50? The frost nova is about 150 wide isn't it?
- Why have the TriggerSleepAction(0)? If you want it to be instant,
remove this line. If you want it timed, you'll need to do something
else and why set it to 0 anyway? Also i read somewhere (but don't
quote me) that TriggerSleepAction() and PolledWait() can't handle
times under 0.25 seconds, so a timer would be the way to go.

So let us know a bit more detail about what you're trying to do and someone'll be able to help you out.
04-28-2006, 04:53 AM#4
emjlr3
i fgured it out, its all good now, needed to use globals to move my values from the one function to the function in teh ExecuteFunc
04-28-2006, 05:26 AM#5
PipeDream
GetExpiredTimer() works in ExecuteFunc'd threads, so you can still use your GC attached vars.