• 🏆 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] Can't Add Delays to Unit Group Function

Status
Not open for further replies.
Level 9
Joined
May 28, 2007
Messages
365
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
 
Level 9
Joined
May 28, 2007
Messages
365
I have no idea what you just said, but here is a fix I was thinking of.

Have an udg_variable (arrays) of all the called stuff, and then clear the data in the array variables at the end of the function.

My trouble is how do I add all the effects generated and organize them into an array?
 
Level 40
Joined
Dec 14, 2005
Messages
10,532
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
 
Level 12
Joined
Apr 27, 2008
Messages
1,228
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.
Top