• 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.

[Trigger] Overlapping of events

Status
Not open for further replies.
Level 5
Joined
Feb 17, 2011
Messages
95
I have a trigger with 2 events: EVENT_PLAYER_UNIT_SPELL_EFFECT and EVENT_PLAYER_UNIT_DEATH.

There are no conditions before this if statements and trigger basically looked like this:
JASS:
if GetDyingUnit() == udg_hero then
    call EndSpell()    
elseif GetSpellAbilityId() == 'A001' then
    call EndSpell()
elseif GetSpellAbilityId() == 'A002' then
    // Some Actions...
elseif GetSpellAbilityId() == 'A003' then
    // Some Actions...
endif
And it worked fine for some time, until it started running EndSpell() on EVENT_PLAYER_UNIT_SPELL_EFFECT from
if GetDyingUnit() == udg_hero then.

So i moved that if block to the end, and it works now:

JASS:
if GetSpellAbilityId() == 'A001' then
    call EndSpell()
elseif GetSpellAbilityId() == 'A001' then
    // Some Actions...
elseif GetSpellAbilityId() == 'A001' then
    // Some Actions...
elseif GetDyingUnit() == udg_hero then
    call EndSpell()
endif
My question is how can this occur, and can i expect it again?

Edit: Not sure if this is the right place to post this..
 
Level 5
Joined
Feb 17, 2011
Messages
95
udg_spiritsHero[0] was simplified in first post to udg_hero
JASS:
// This trigger is used for initiating/ending spell

function IsUnitAliveAndHostileEndSpell takes nothing returns boolean
    // This function is filter for damageGroup unit group
    
    return GetBooleanAnd(GetBooleanAnd(GetWidgetLife(GetFilterUnit()) > 0.405, not IsUnitType(GetFilterUnit(), UNIT_TYPE_DEAD)), IsUnitEnemy(GetFilterUnit(), GetOwningPlayer(udg_spiritsHero[0])))
endfunction

function EndSpell takes nothing returns nothing
    // This function is used to end spell if caster dies
    // or if spell is used before duration expire
    
    local integer c = 1                                                       // c; integer; counter, helper variable  
    local unit fog                                                            // fog; unit; first of group; used for damageGroup unit group
    
    call DisableTrigger(gg_trg_Spirits_Create_Move)                           // Disables Spirit Create Move and
    call DisableTrigger(gg_trg_Spirits_Damage)                                // Spirits Damage trigger
    call UnitRemoveAbility(udg_spiritsHero[0], udg_abilityUnitID[1])          // Removes Push Out and
    call UnitRemoveAbility(udg_spiritsHero[0], udg_abilityUnitID[2])          // Pull In abilities 
    
    loop                                                                      // Reamaining Spirits burst at the end of spell, releasing damage
        exitwhen c > 5 
        // If Spirit is alive
        if GetBooleanAnd(GetWidgetLife(udg_spiritsHero[c]) > 0.405, not IsUnitType(udg_spiritsHero[c], UNIT_TYPE_DEAD)) then
            call KillUnit(udg_spiritsHero[c])                                 // Spirit explode at the end of spell
            // Picking units in group for aoe damage around each Spirit
            call GroupEnumUnitsInRange(udg_damageGroup, GetUnitX(udg_spiritsHero[c]), GetUnitY(udg_spiritsHero[c]), udg_damageHero[0], Filter(function IsUnitAliveAndHostileEndSpell))
            loop
                set fog = FirstOfGroup(udg_damageGroup)
                exitwhen fog == null
                // Damaging unit in group
                call UnitDamageTarget(udg_spiritsHero[0], fog, udg_damageUnit[GetUnitAbilityLevel(udg_spiritsHero[0], udg_abilityUnitID[0])], false, false, udg_attackType, udg_damageType, WEAPON_TYPE_WHOKNOWS)
                call GroupRemoveUnit(udg_damageGroup, fog)
            endloop
        endif
        set udg_spiritsHero[c] = null
        set c = c + 1
    endloop
    set udg_spiritsHero[0] = null 
endfunction

All triggers are in signature.
 
Get rid of the BJs. The red text.
Example.
JASS:
if GetBooleanAnd(GetWidgetLife(udg_spiritsHero[c]) > 0.405, not IsUnitType(udg_spiritsHero[c], UNIT_TYPE_DEAD)) then
-->
JASS:
if GetWidgetLife(udg_spiritsHero[c]) > 0.405 and not IsUnitType(udg_spiritsHero[c], UNIT_TYPE_DEAD) then
You should take a look at my tutorial Converting GUI to efficient JASS.

Also for the above you never check for removed units. You need to change the above to this.
JASS:
if GetWidgetLife(udg_spiritsHero[c]) > 0.405 and not IsUnitType(udg_spiritsHero[c], UNIT_TYPE_DEAD) and GetUnitTypeId != 0 then

I'm guessing that this spell is not MUI ?
The problem may be in this line.
JASS:
set udg_spiritsHero[0] = null
You are setting the above to null then if it runs again you are using udg_spiritsHero[0] to damage the unit which may be breaking the spell.
I don't know if killing a dead unit is good to do. You can remove the dead unit.
 
Level 5
Joined
Feb 17, 2011
Messages
95
Get rid of the BJs. The red text.
Example.
JASS:
if GetBooleanAnd(GetWidgetLife(udg_spiritsHero[c]) > 0.405, not IsUnitType(udg_spiritsHero[c], UNIT_TYPE_DEAD)) then
-->
JASS:
if GetWidgetLife(udg_spiritsHero[c]) > 0.405 and not IsUnitType(udg_spiritsHero[c], UNIT_TYPE_DEAD) then
You should take a look at my tutorial Converting GUI to efficient JASS.
I thought GetBooleanAnd/Or had to be used, this simplifies everything, so yeah, i should read your tutorial. :)

Also for the above you never check for removed units. You need to change the above to this.
JASS:
if GetWidgetLife(udg_spiritsHero[c]) > 0.405 and not IsUnitType(udg_spiritsHero[c], UNIT_TYPE_DEAD) and GetUnitTypeId != 0 then
Thank you for pointing that out.

I'm guessing that this spell is not MUI ?
The problem may be in this line.
JASS:
set udg_spiritsHero[0] = null
You are setting the above to null then if it runs again you are using udg_spiritsHero[0] to damage the unit which may be breaking the spell.
I don't know if killing a dead unit is good to do. You can remove the dead unit.
It's not MUI.
I did some testings and udg_spiritsHero[0] did cause the problems where you said. Also it caused problem since udg_spiritsHero[0] wasn't set before the first time spell was used, so checking if GetDyingUnit() == udg_spiritsHero[0] caused problem when it's on top.
Anyway it must to be at the bottom.

Thanks for all the help. :)

JASS:
// This trigger is used for initiating/ending spell

function IsUnitAliveAndHostileEndSpell takes nothing returns boolean
    // This function is filter for damageGroup unit group
    
    return GetWidgetLife(GetFilterUnit()) > 0.405 and not IsUnitType(GetFilterUnit(), UNIT_TYPE_DEAD) and IsUnitEnemy(GetFilterUnit(), GetOwningPlayer(udg_spiritsHero[0])) and GetUnitTypeId(GetFilterUnit()) != 0
endfunction

function EndSpell takes nothing returns nothing
    // This function is used to end spell if caster dies
    // or if spell is used before duration expire
    
    local integer c = 1                                                       // c; integer; counter, helper variable  
    local unit fog                                                            // fog; unit; first of group; used for damageGroup unit group
    
    call DisableTrigger(gg_trg_Spirits_Create_Move)                           // Disables Spirit Create Move and
    call DisableTrigger(gg_trg_Spirits_Damage)                                // Spirits Damage trigger
    call UnitRemoveAbility(udg_spiritsHero[0], udg_abilityUnitID[1])          // Removes Push Out and
    call UnitRemoveAbility(udg_spiritsHero[0], udg_abilityUnitID[2])          // Pull In abilities 
    
    loop                                                                      // Reamaining Spirits burst at the end of spell, releasing damage
        exitwhen c > 5 
        // If Spirit is alive
        if GetWidgetLife(udg_spiritsHero[c]) > 0.405 and not IsUnitType(udg_spiritsHero[c], UNIT_TYPE_DEAD) and GetUnitTypeId(udg_spiritsHero[c]) != 0 then
            call KillUnit(udg_spiritsHero[c])                                 // Spirit explode at the end of spell
            // Picking units in group for aoe damage around each Spirit
            call GroupEnumUnitsInRange(udg_damageGroup, GetUnitX(udg_spiritsHero[c]), GetUnitY(udg_spiritsHero[c]), udg_damageHero[0], Filter(function IsUnitAliveAndHostileEndSpell))
            loop
                set fog = FirstOfGroup(udg_damageGroup)
                exitwhen fog == null
                // Damaging unit in group
                call UnitDamageTarget(udg_spiritsHero[0], fog, udg_damageUnit[GetUnitAbilityLevel(udg_spiritsHero[0], udg_abilityUnitID[0])], false, false, udg_attackType, udg_damageType, WEAPON_TYPE_WHOKNOWS)
                call GroupRemoveUnit(udg_damageGroup, fog)
            endloop
        endif
        set c = c + 1
    endloop 
endfunction
  
function Trig_Spirits_Initiate_End_Spell_Actions takes nothing returns nothing
    // This function is used to detect which ability is being used,
    // to set/reset spell values
    // and to end spell if caster dies 
    
    local integer  c = 1                                                      // c; integer; counter, helper variable
    
    if GetDyingUnit() == udg_spiritsHero[0] then
        call EndSpell()                                                       // Ending spell if caster dies before duration expire 
  
    // =========== Ability being used is Spirits ==================================================
    elseif GetSpellAbilityId() == udg_abilityUnitID[0] then
        call EndSpell()                                                       // Ending spell if activated before duration expire
        
        // ========== Reseting spell values ===========================================                
        call TimerStart(udg_durationTimer, udg_durationTime, false, function EndSpell)  // Start/Restart spell duration timer
        // angDist; real; angle distance 
        set udg_distanceAngle[0] = udg_distanceAngle[8]                       // angle of Spirits while moving
        set udg_distanceAngle[1] = udg_oscillationDistRange[1]                // distance of Spirits while moving 
        set udg_distanceAngle[2] = udg_distanceAngle[8]                       // angle of Spirits while created
        set udg_distanceAngle[3] = 0                                          // distance of Spirits while created
        set udg_distanceAngle[7] = 0                                          // counts number of iterations
        //  angDistBool; boolean; used for controling Push Out and Pull In abilities
        set udg_distanceOscillation[1] = false                                // Push Out
        set udg_distanceOscillation[2] = false                                // Pull In
        // nSpirits; integer; counts number of spirits
        set udg_nSpirits[1] = 1                                               // Number of created Spirits 
        set udg_nSpirits[2] = 5                                               // Current number of Spirits
        // spiritsHero; unit; [1]-[5] are Spirits
        set udg_spiritsHero[0] = GetTriggerUnit()                             // [0] is caster  
        call EnableTrigger(gg_trg_Spirits_Create_Move)                        // Starts creating and moving Spirits
        call EnableTrigger(gg_trg_Spirits_Damage)                             // Enables Spirits damage

    // =========== Ability being used is Push Out =================================================
    elseif GetSpellAbilityId() == udg_abilityUnitID[1] then
        if udg_distanceAngle[1] == udg_oscillationDistRange[2] then                      // If distance of oscillation is maximal:
            set udg_distanceOscillation[1] = false                                       // turn off Push Out
        elseif udg_distanceOscillation[1] == true then                                   // Sets Spirits oscillation distance at current if
            set udg_distanceOscillation[1] = false                                       // casted while pushing out 
        else
            set udg_distanceOscillation[2] = false                                       // Turn off Pull In
            set udg_distanceOscillation[1] = true                                        // Turn on Push Out
            set udg_distanceAngle[1] = udg_distanceAngle[1] + udg_distanceAngle[5]       // Incerease oscillation distance
        endif
    
    // ========= Ability being used is Pull In ==================================================
    elseif GetSpellAbilityId() == udg_abilityUnitID[2] then
        if udg_distanceAngle[1] == udg_oscillationDistRange[1] then                       // If distance of oscillation is minimal: 
            set udg_distanceOscillation[2] = false                                        // turn off Pull In
        elseif udg_distanceOscillation[2] == true then                                    // Sets Spirits oscillation distance at current if
            set udg_distanceOscillation[2] = false                                        // casted while pulling in
        else
            set udg_distanceOscillation[1] = false                                        // Turn off Push Out
            set udg_distanceOscillation[2] = true                                         // Turn on Pull In
            set udg_distanceAngle[1] = udg_distanceAngle[1] - udg_distanceAngle[5]        // Decrease oscillation distance
        endif               
    endif
endfunction

// ======================= Init Trigger Spirits Initiate End Spell =========================================================
function InitTrig_Spirits_Initiate_End_Spell takes nothing returns nothing
    set gg_trg_Spirits_Initiate_End_Spell = CreateTrigger()
    call TriggerRegisterAnyUnitEventBJ(gg_trg_Spirits_Initiate_End_Spell, EVENT_PLAYER_UNIT_SPELL_EFFECT)
    call TriggerRegisterAnyUnitEventBJ(gg_trg_Spirits_Initiate_End_Spell, EVENT_PLAYER_UNIT_DEATH)
    call TriggerAddAction(gg_trg_Spirits_Initiate_End_Spell, function Trig_Spirits_Initiate_End_Spell_Actions)
endfunction
 
Level 5
Joined
Feb 17, 2011
Messages
95
Already did, as well as few other tutorials, and it doesn't seem hard. But i am postponing MUI part of the spell, since there are still some things that i have to learn about general JASS coding and spell making.
 
Status
Not open for further replies.
Top