• Check out the results of the Techtree Contest #19!
  • 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.
  • Create a void inspired texture for Warcraft 3 and enter Hive's 34th Texturing Contest: Void! Click here to enter!
  • The Hive's 22nd Icon Contest: Creep Abilities is now concluded, time to vote for your favourite set of icons! Click here to vote!

[JASS] Can't Add Delays to Unit Group Function

Status
Not open for further replies.
Level 9
Joined
May 28, 2007
Messages
364
Why is this trigger not working?

I'm trying to make a temp. AoE life drain. Everything works except the spell effects and lightning are being removed. Before you say "why did you call a function to cleanup, instead of doing it in the original function", it's because I already tried a TriggerSleepAction in the original function, and it didn't work.

JASS:
function Trig_Life_Drain_Conditions takes nothing returns boolean
    if ( not ( GetSpellAbilityId() == 'A007' ) ) then
        return false
    endif
    return true
endfunction

function Cleanup takes effect e, effect et, lightning l, unit u returns nothing
call TriggerSleepAction(1)
call PauseUnit(u, false)
call DestroyEffect(e)
call DestroyEffect(et)
call DestroyLightning(l)
endfunction

function DrainLife takes nothing returns nothing
local unit u = GetTriggerUnit()
local unit t = GetEnumUnit()
local location l = GetUnitLoc(u) 
local location lt = GetUnitLoc(t)
local integer i = GetUnitAbilityLevel(u, 'A007')
local real life = GetUnitState(u, UNIT_STATE_LIFE) + ( (I2R(i)*20)+20 )
local real dam = I2R(i)*20+20
local lightning light = AddLightningEx("DRAL", true, GetLocationX(l), GetLocationY(l), 10, GetLocationX(lt), GetLocationY(lt), 10)
local effect e = AddSpecialEffectTarget("Abilities\\Spells\\Other\\Drain\\DrainTarget.mdl", t, "head")
local effect et = AddSpecialEffectTarget("Abilities\\Spells\\Other\\Drain\\DrainCaster.mdl", u, "head")
call PauseUnit(t, true)
call UnitDamageTarget(u, t, dam, true, false, ATTACK_TYPE_CHAOS, DAMAGE_TYPE_NORMAL, WEAPON_TYPE_WHOKNOWS)
call SetUnitState(u, UNIT_STATE_LIFE, life)
call Cleanup(e, et, light, t)
endfunction

function CheckEnemyA takes nothing returns boolean
return ( IsUnitEnemy(GetFilterUnit(), GetOwningPlayer(GetTriggerUnit())) == TRUE )
endfunction

function CheckEnemyB takes nothing returns boolean
return ( ( GetUnitState(GetFilterUnit(), UNIT_STATE_LIFE) > 0 ) == TRUE )
endfunction

function CheckEnemy takes nothing returns boolean
return GetBooleanAnd(CheckEnemyA(), CheckEnemyB())
endfunction

function Trig_Life_Drain_Actions takes nothing returns nothing
local group g = GetUnitsInRangeOfLocMatching(400, GetUnitLoc(GetTriggerUnit()), Condition(function CheckEnemy))
call ForGroup(g, function DrainLife)
call DestroyGroup(g)
endfunction

//===========================================================================
function InitTrig_Life_Drain takes nothing returns nothing
    set gg_trg_Life_Drain = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_Life_Drain, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddCondition( gg_trg_Life_Drain, Condition( function Trig_Life_Drain_Conditions ) )
    call TriggerAddAction( gg_trg_Life_Drain, function Trig_Life_Drain_Actions )
endfunction
 
What I mean is something like --

(globals: Special Effect sfx)

JASS:
function Cleanup takes nothing returns nothing
    local effect e = udg_sfx
    local effect e2 = bj_lastCreatedEffect
    local lightning l = bj_lastCreatedLightning
    local unit u = bj_lastCreatedUnit
    call TriggerSleepAction(1)
    call PauseUnit(u,false)
    call DestroyLightning(l)
    call DestroyEffect(e)
    call DestroyEffect(e2)
    set u = null
    set l = null
    set e = null
    set e2 = null
endfunction

function MyEnum takes nothing returns nothing
    ...
    set udg_sfx = <some effect>
    set bj_lastCreatedEffect = <some other effect>
    set bj_lastCreatedUnit = <enumed unit>
    set bj_lastCreatedLightning = <some lightning>
    call ExecuteFunc("Cleanup")
    ...
endfunction
 
Poot is right(as usual)
But I will clarify why:
JASS:
function b takes nothing returns nothing
call TriggerSleepAction(1)
call BJDebugMsg("3")
endfunction

function a takes nothing returns nothing
call BJDebugMsg("1")
call b()
call BJDebugMsg("2")
endfunction
does not work :P
Because when you call b the normal way, it is executed in the same thread(that is wc3 thread).
Meaning "2" will appear after "3", no matter what time you input in TriggerSleepAction.
Basically when you call b from a, the code in a continues only after b has finished.
We could say that wc3 does this with the code:
JASS:
function a takes nothing returns nothing
call BJDebugMsg("1")
call TriggerSleepAction(1)
call BJDebugMsg("3")
call BJDebugMsg("2")
endfunction
To initiate a new thread(wc3 thread) you can use ExecuteFunction("b"), but then function b has to take nothing. Also a timer callback is executed in a new thread(wc3 thread), but yet again no values can be passed.
So you need global variables as Poot has shown.
In vJass you could just use structs which would allow you to only need one global integer variable. Aside from that vJass offers other ways of calling functions, but still you cant pass values with them.
 
Status
Not open for further replies.
Back
Top