• 🏆 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!

[Trigger] Simple trigger occasionally does not work

Status
Not open for further replies.

SpasMaster

Hosted Project: SC
Level 23
Joined
Jan 29, 2010
Messages
1,969
Hello, Hive.

I have been experiencing an issue with a simple ability and I cannot figure out what can be the reason for it. So, let me explain what the ability does and what exactly is the issue.

Shatter is a single target ability that instantly deals damage. If the Hero (Ice Lancer) is buffed by Frost Armor, it is consumed, but the damage dealt is increased and the target is stunned.
(There is also a Talent in there that disables that Frost Armor-consumption effect)

Pretty simple. Yet occasionally the trigger apparently does not execute. No damage is dealt, nothing happens. I still cannot find any pattern as to when exactly it does not work, otherwise I would've been able to locate the issue. Something, somewhere, sometimes for some reason prevents the damage to be dealt.

Now, this is an ability in Sunken City which has hundreds of triggers, so the reason for this could be many things. I am not expecting a specific response saying "This is the reason" but rather a lead. What could cause such behavior? What should I be looking for? How would you advise me to narrow down the possibilities?

Here are a couple of important notes:
• The Shatter trigger does not interact directly with any other triggers (it's not turned on/off by anything)
• I figured the [Shatter_Damage] variable could be getting changed somewhere else (to 0 for example), thus resulting in no damage. That's not the case. The variable is only used in this trigger.
• In the Object Editor, the ability is based off Chain Lightning with 1 target and 0 damage.

And finally, here is the trigger itself:

[trigger=""]
Shatter
Events
Unit - A unit Starts the effect of an ability
Conditions
(Ability being cast) Equal to Shatter
Actions
Set Generic_Point = (Position of (Triggering unit))
Set Shatter_Damage = ((90.00 x (Real((Level of Shatter for (Triggering unit))))) + (2.65 x (Real((Agility of (Triggering unit) (Include bonuses))))))
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
If - Conditions
(Talents_Unit[1] has an item of type Snowy Bond) Equal to True
Then - Actions
Else - Actions
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
If - Conditions
((Triggering unit) has buff Frost Armor (Troll)) Equal to True
Then - Actions
If (All Conditions are True) then do (Then Actions) else do (Else Actions)
If - Conditions
(Talents_Unit[1] has an item of type Icebreak) Equal to True
Then - Actions
Set Shatter_Damage = (Shatter_Damage x 1.60)
Else - Actions
Set Shatter_Damage = (Shatter_Damage x 1.30)
Unit - Create 1 Dummy (Generic Uses) for (Owner of (Triggering unit)) at Generic_Point facing Default building facing degrees
Unit - Add Shatter Stun to (Last created unit)
Unit - Add a 1.00 second Generic expiration timer to (Last created unit)
Unit - Order (Last created unit) to Human Mountain King - Storm Bolt (Target unit of ability being cast)
Unit - Remove Frost Armor (Troll) buff from (Triggering unit)
Else - Actions
Unit - Cause (Triggering unit) to damage (Target unit of ability being cast), dealing Shatter_Damage damage of attack type Spells and damage type Normal
Custom script: call RemoveLocation(udg_Generic_Point)
[/trigger]
 
Last edited:
Level 10
Joined
Oct 5, 2008
Messages
355
The trigger itself looks fine. I would think it has a problem with the overlying systems (especially the damage engine)

A questions:

I believe that you have a talent that resets the cooldown of the q ability of a hero? Does that for a reason remove and add the ability? I don't know how the threads are handled exactly in that case, but it could lead to the "level of ability being cast" " give out a zero.

What could happen is a case of thread breakdown, that at some point of the danage calculation, the thread terminates. I would look at the dds you use.

Oh, i saw the stun ability. Every stun ability i know causes a dds to fire (a 0 damage one). Could tgis one potentionally fudge up the variables? (Potentionally the triggering unit and target of ability being cast variables, but i dont kbow how you handle your dds). The chain lightning ability could cause something like that either, try replace that one with channel. The get around of the stun would be the disable and enable the dds trigger after the stun execution.

And by the way: does icebreak disable the damage increase and the stun either with the removal of the frost armor? Just asking since it doesnt sound intentional.
 

SpasMaster

Hosted Project: SC
Level 23
Joined
Jan 29, 2010
Messages
1,969
I believe that you have a talent that resets the cooldown of the q ability of a hero? Does that for a reason remove and add the ability? I don't know how the threads are handled exactly in that case, but it could lead to the "level of ability being cast" " give out a zero.
If that is the case, then there would still be damage dealt from the Agility scaling. In my case, no damage is dealt at all.
I would look at the dds you use.
I am using Damage Engine 3.7.0.1
Oh, i saw the stun ability. Every stun ability i know causes a dds to fire (a 0 damage one). Could tgis one potentionally fudge up the variables? (Potentionally the triggering unit and target of ability being cast variables, but i dont kbow how you handle your dds).
I have condition in my DDS to not run if the damage is 0, precisely for that reason :p
And by the way: does icebreak disable the damage increase and the stun either with the removal of the frost armor? Just asking since it doesnt sound intentional.
Icebreak simply increases the damage dealt :O
 
Level 18
Joined
Nov 21, 2012
Messages
835
Your Shatter trigger looks fine for me, except one minor thing: it is good habit to always add expiration timer to unit after creation.

You said sometimes trigger does not execute: does it mean nothing happeds : no damage and no stun (if hero has buff)?

Again I would not blame your trigger for bugs. Even if Talents_Unit[1] will be null it won't crash your trigger (condition will return 'false')
So the only conclusion is : the reason is outside this trigger. So how did you check if trigger is not turned off and/or variable Shatter_Damage is not overwriten? If n Object Manager (F11) - this is incomplete check. Let me suggest to make intended mistake in jass trigger (or mistake in custom script inside gui trigger) to open jass parser error window. Then right-click on window, select all and copy and paste into new txt file. Then search in this txt file for udg_Shatter_Damage and gg_trg_Shatter. Only after these checks you can be 100% sure that variable and trigger are not referenced anywhere.
 

SpasMaster

Hosted Project: SC
Level 23
Joined
Jan 29, 2010
Messages
1,969
You said sometimes trigger does not execute: does it mean nothing happeds : no damage and no stun (if hero has buff)?
I am not sure actually. I am not sure if the stun part gets skipped. I will have to double check this.
So how did you check if trigger is not turned off and/or variable Shatter_Damage is not overwriten?
-If "Trigger A" is turned on/off in another trigger via the <Turn on/off trigger> action, then deleting "Trigger A" will disable these actions in all affected triggers and will disable the triggers as well. That's an easy way to track down if other triggers turn on/off "Trigger A". Once tracked, everything is easily reversed with Undo.

-Same logic applies to the Shatter_Damage variable. If you delete the variable itself in the trigger editor, then it disables all triggers that use that variable in any way. Once more, as soon as you see the affected triggers, you just Undo to fix the broken actions.
Let me suggest to make intended mistake in jass trigger (or mistake in custom script inside gui trigger) to open jass parser error window. Then right-click on window, select all and copy and paste into new txt file. Then search in this txt file for udg_Shatter_Damage and gg_trg_Shatter. Only after these checks you can be 100% sure that variable and trigger are not referenced anywhere.
I will try this as well. Stay tuned for update.
 

SpasMaster

Hosted Project: SC
Level 23
Joined
Jan 29, 2010
Messages
1,969
Ok, update:
I asked players in my Discord Server to test out Shatter while looking if consuming Frost Armor actually impacts the bug in any way. Based on player feedback, the bug seems to occur only when Frost Armor is consumed. However, the stun still happens even if the bug occurs and no damage is dealt.

Regarding the jass parser error window:
So, here is where udg_Shatter_Damage is referenced,
1) It can be seen where global variables are initialized. (Pic 1)
2) It can be seen further down the list. It appears to still be among other variables that are initialized although I am not exactly sure. (Pic 2)
3) Finally it can be seen where it belongs - in the Shatter trigger.
JASS:
//===========================================================================
// Trigger: Shatter
//===========================================================================
function Trig_Shatter_Conditions takes nothing returns boolean
    if ( not ( GetSpellAbilityId() == 'A0CN' ) ) then
        return false
    endif
    return true
endfunction

function Trig_Shatter_Func003Func001Func001C takes nothing returns boolean
    if ( not ( UnitHasItemOfTypeBJ(udg_Talents_Unit[1], 'I0KM') == true ) ) then
        return false
    endif
    return true
endfunction

function Trig_Shatter_Func003Func001C takes nothing returns boolean
    if ( not ( UnitHasBuffBJ(GetTriggerUnit(), 'B02Q') == true ) ) then
        return false
    endif
    return true
endfunction

function Trig_Shatter_Func003C takes nothing returns boolean
    if ( not ( UnitHasItemOfTypeBJ(udg_Talents_Unit[1], 'I0KN') == true ) ) then
        return false
    endif
    return true
endfunction

function Trig_Shatter_Actions takes nothing returns nothing
    set udg_Generic_Point = GetUnitLoc(GetTriggerUnit())
    set udg_Shatter_Damage = ( ( 90.00 * I2R(GetUnitAbilityLevelSwapped('A0CN', GetTriggerUnit())) ) + ( 2.65 * I2R(GetHeroStatBJ(bj_HEROSTAT_AGI, GetTriggerUnit(), true)) ) )
    if ( Trig_Shatter_Func003C() ) then
    else
        if ( Trig_Shatter_Func003Func001C() ) then
            if ( Trig_Shatter_Func003Func001Func001C() ) then
                set udg_Shatter_Damage = ( udg_Shatter_Damage * 1.60 )
            else
                set udg_Shatter_Damage = ( udg_Shatter_Damage * 1.30 )
            endif
            call CreateNUnitsAtLoc( 1, 'h002', GetOwningPlayer(GetTriggerUnit()), udg_Generic_Point, bj_UNIT_FACING )
            call UnitAddAbilityBJ( 'A0HG', GetLastCreatedUnit() )
            call UnitApplyTimedLifeBJ( 1.00, 'BTLF', GetLastCreatedUnit() )
            call IssueTargetOrderBJ( GetLastCreatedUnit(), "thunderbolt", GetSpellTargetUnit() )
            call UnitRemoveBuffBJ( 'B02Q', GetTriggerUnit() )
        else
        endif
    endif
    call UnitDamageTargetBJ( GetTriggerUnit(), GetSpellTargetUnit(), udg_Shatter_Damage, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_NORMAL )
    call RemoveLocation(udg_Generic_Point)
endfunction

//===========================================================================
function InitTrig_Shatter takes nothing returns nothing
    set gg_trg_Shatter = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_Shatter, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddCondition( gg_trg_Shatter, Condition( function Trig_Shatter_Conditions ) )
    call TriggerAddAction( gg_trg_Shatter, function Trig_Shatter_Actions )
endfunction
 

Attachments

  • 1.png
    1.png
    17.9 KB · Views: 78
  • 2.png
    2.png
    12.7 KB · Views: 58
Level 10
Joined
Oct 5, 2008
Messages
355
Have you tried doing a run with debug messages? They can be usefull in determining if a function goes rogue or just idnt called at all. Place an ingame message after each if/then/else block with corresponding infirmation (can be a Countrr from 1 to x or the value of shatter damage or even the unit id of the target) if some messages arent shown or have the wrong values Yaou directly have an indicator where exactly the problem happens. Of course it would be better if the bug could easiliy be reproduced, but at least it gives away a place to begin with.
 
Level 18
Joined
Nov 21, 2012
Messages
835
1.png is global declaration, 2.png is initialization, so nothing wrong with variable udg_Shatter_Damage.
Based on player feedback, the bug seems to occur only when Frost Armor is consumed. However, the stun still happens even if the bug occurs and no damage is dealt.
if those reports are true it complicates problem even more, if stun applies and frost buff is removed from the caster so I see no way to affect the last line of the trigger. What are the changes between caster/target with and without frost armor buff? Target: none (storm bolt is not instant, target is not stunned at this moment yet), Caster: will have frost buff removed. It all doesnt affect last line : 'unit damage target'.

Possible case: you're using in last line Attack Type: spells, Damage Type: Physical. This combination affect spell immune targets and will not affect ethereal. Is this possible that target is ethereal?

And finaly I susspect DDS itself or your DDS triggers.
Or maybe target has magic damage reduction ability like runed bracers or elune that messed up DDS calculations? This supposed to be triggered (if Im not mistaken) when using DDS.
 

SpasMaster

Hosted Project: SC
Level 23
Joined
Jan 29, 2010
Messages
1,969
Is this possible that target is ethereal?
No, 100% not ethereal.
And finaly I susspect DDS itself or your DDS triggers.
I do suspect that as well. However, it still only happens sometimes when consuming Frost Armor. I am still not certain what is it within the DDS that causes this whole issue.
Or maybe target has magic damage reduction ability like runed bracers or elune that messed up DDS calculations? This supposed to be triggered (if Im not mistaken) when using DDS.
I do have this side covered up. If there was a problem with magic damage reduction/runed bracers/elune's grace/etc, then it would've affected literally all spells in the game, which it does not.
 
Level 13
Joined
Jul 15, 2007
Messages
763
To rule out any interferance from other systems in your map, you should try creating other variables for everything in that trigger (i.e. Shatter_Caster and Shatter_Target). I occaisonally get a problem in my map where i create a spell with good looking code, but it gets interrupted by reactive triggers in the map. Triggering unit is reliable as far as i know, but 'target unit of ability being cast' is NOT and you need to use it very carefully, and use variables in longer triggers.

In fact, i am confident the problem is with your trigger using 'target unit of ability being cast'.

Imagine this:

In your trigger, 'target unit of ability being cast' is going to be your Shatter target, right?

Big problem. You order a dummy unit to cast a spell during this trigger. And you use 'target unit of ability being cast' after the dummy uses its spells.

And this is why 'target unit of ability being cast' can go wrong, because suddenly you're casting a spell, within a spell.

NOW normally, this is actually ok, because most casters have a cast point, so their cast wont fire during a trigger, BUT...

I guess your dummy has a cast point of 0.00

This basically means that 'target unit of ability being cast' becomes no-unit (i don't know why, maybe brainy @Dr Super Good knows?)

Here's a simple test map to see it in action:

It's quite simple. There's a Shaman and a Priest. The Priest casts Heal on the Shaman that does 500 damage. But when the Priest casts Heal, the Shaman will cast Purge on the Priest. The Shaman's cast point is 0. The heal does no damage to the Shaman until he can't cast purge (oom), because the purge interferes with the trigger.
 

Attachments

  • targetunitofabil.w3x
    16.8 KB · Views: 41

SpasMaster

Hosted Project: SC
Level 23
Joined
Jan 29, 2010
Messages
1,969
Holy shit, this is... so simple and logical, yet it would've never occurred to me that it works that way. Now that you explained it and that I've realized how it works, I am pretty sure that will be my issue as well, because the stun is a storm bolt with cast point of 0.00.
I will soon apply your fix suggestion and will confirm if it's fixed or not.

Regardless, thanks for the help.
+rep to everyone who responded in the thread so far
 
Status
Not open for further replies.
Top