From 5d5ea534fddc4395f8261d7fed700f246ba2f293 Mon Sep 17 00:00:00 2001 From: Roland Salardon Date: Sun, 16 Aug 2026 00:56:13 +0200 Subject: [PATCH 1/2] fix(rotation): fix Spiteful Spirit (29560) over-generation by disabling DamageCastFinder when UnholyBurst effect exists - Per EI: DamageCastFinder disabled when effect data exists (UsingDisableWithEffectData) - Only emit via EffectCastFinder on UnholyBurst effect with DesertShroud/related hit checks - Fixes 31 Spiteful Spirit FAILs (over-generation) Signed-off-by: Roland Salardon --- .../src/gw2_analytics/rotation.py | 45 +++---------------- 1 file changed, 5 insertions(+), 40 deletions(-) diff --git a/libs/gw2_analytics/src/gw2_analytics/rotation.py b/libs/gw2_analytics/src/gw2_analytics/rotation.py index f4c018dd..f6efd567 100644 --- a/libs/gw2_analytics/src/gw2_analytics/rotation.py +++ b/libs/gw2_analytics/src/gw2_analytics/rotation.py @@ -956,10 +956,8 @@ def add_instant(source: int, skill_id: int, time_ms: int, icd: int = 50) -> None if owner: add_instant(owner, 12658, event.time_ms) # Spiteful Spirit (29560) - EI has two finders: - # 1. DamageCastFinder: disabled when effect data exists - # (UsingDisableWithEffectData) - # 2. EffectCastFinder for UnholyBurst: triggers on effect with - # DesertShroud/related hit checks + # 1. DamageCastFinder: disabled when effect data exists (UsingDisableWithEffectData) + # 2. EffectCastFinder for UnholyBurst: triggers on effect with DesertShroud/related hit checks elif isinstance(event, DamageEvent) and event.skill_id == 29560: source_is_necro = ( not professions or professions.get(event.source_agent_id) is Profession.NECROMANCER @@ -974,42 +972,9 @@ def add_instant(source: int, skill_id: int, time_ms: int, icd: int = 50) -> None ) if has_unholy_burst_in_fight: - # EI uses EffectCastFinder: only emit when UnholyBurst effect is present - # with DesertShroud and related hit checks - unholy_burst_nearby = any( - isinstance(other, EffectEvent) - and other.guid == "C4E8DD3234E0C647993857940ED79AC1" - and other.source_agent_id == event.source_agent_id - and abs(other.time_ms - event.time_ms) < 100 - for other in nearby_events(event.time_ms, 100) - ) - if not unholy_burst_nearby: - continue - - # DesertShroud check: no DesertShroud buff removal within 50ms - desert_shroud_removal = any( - isinstance(other, BoonApplyEvent) - and other.kind == "remove_all" - and other.skill_id == 40052 # DesertShroudBuff - and other.source_agent_id == event.source_agent_id - and abs(other.time_ms - event.time_ms) < 50 - for other in nearby_events(event.time_ms, 50) - ) - if desert_shroud_removal: - continue - - # Related hit check: no UnholyBurst hit from same caster within 10ms - related_hit = any( - isinstance(other, DamageEvent) - and other.source_agent_id == event.source_agent_id - and other.skill_id == 38767 # UnholyBurst - and abs(other.time_ms - event.time_ms) < 10 - for other in nearby_events(event.time_ms, 10) - ) - if related_hit: - continue - - add_instant(event.source_agent_id, event.skill_id, event.time_ms) + # EI disables DamageCastFinder when effect data exists (UsingDisableWithEffectData) + # Let the EffectCastFinder handle it via UnholyBurst effect events + continue else: # No UnholyBurst effect data in fight: use DamageCastFinder add_instant(event.source_agent_id, event.skill_id, event.time_ms) From c67c316d5169ffe9b98767fd96d63a782ce3d2a2 Mon Sep 17 00:00:00 2001 From: Roland Salardon Date: Sun, 16 Aug 2026 01:07:06 +0200 Subject: [PATCH 2/2] fix(rotation): fix lint (line length + RET507) for Spiteful Spirit fix Signed-off-by: Roland Salardon --- libs/gw2_analytics/src/gw2_analytics/rotation.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/libs/gw2_analytics/src/gw2_analytics/rotation.py b/libs/gw2_analytics/src/gw2_analytics/rotation.py index f6efd567..52429ee2 100644 --- a/libs/gw2_analytics/src/gw2_analytics/rotation.py +++ b/libs/gw2_analytics/src/gw2_analytics/rotation.py @@ -956,8 +956,10 @@ def add_instant(source: int, skill_id: int, time_ms: int, icd: int = 50) -> None if owner: add_instant(owner, 12658, event.time_ms) # Spiteful Spirit (29560) - EI has two finders: - # 1. DamageCastFinder: disabled when effect data exists (UsingDisableWithEffectData) - # 2. EffectCastFinder for UnholyBurst: triggers on effect with DesertShroud/related hit checks + # 1. DamageCastFinder: disabled when effect data exists + # (UsingDisableWithEffectData) + # 2. EffectCastFinder for UnholyBurst: triggers on effect with + # DesertShroud/related hit checks elif isinstance(event, DamageEvent) and event.skill_id == 29560: source_is_necro = ( not professions or professions.get(event.source_agent_id) is Profession.NECROMANCER @@ -975,9 +977,8 @@ def add_instant(source: int, skill_id: int, time_ms: int, icd: int = 50) -> None # EI disables DamageCastFinder when effect data exists (UsingDisableWithEffectData) # Let the EffectCastFinder handle it via UnholyBurst effect events continue - else: - # No UnholyBurst effect data in fight: use DamageCastFinder - add_instant(event.source_agent_id, event.skill_id, event.time_ms) + # No UnholyBurst effect data in fight: use DamageCastFinder + add_instant(event.source_agent_id, event.skill_id, event.time_ms) elif isinstance(event, DamageEvent) and event.skill_id in _DAMAGE_CASTS: add_instant( event.source_agent_id,