Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions libs/gw2_analytics/src/gw2_analytics/rotation.py
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,7 @@
62769: 62861,
13135: 13106,
77265: 76730,
29502: -41, # Berserk (end): BuffLossCastFinder(BerserkEndSkill, BerserkBuff)
}
_BUFF_GIVE_CASTS = {
41815: 45789,
Expand Down Expand Up @@ -292,7 +293,7 @@
#: strip is not a cast. Only the entries verified against Elite Insights are
#: listed; the rest keep the historical "any removal" behaviour until they
#: are checked the same way.
_BUFF_LOSS_REMOVE_ALL_ONLY = {29446, 62769}
_BUFF_LOSS_REMOVE_ALL_ONLY = {29446, 62769, 29502}
#: BuffGainCastFinder books the buff gained by the player itself; arcdps
#: also re-emits these buffs with ``src=0`` (env) for trait/sigil pulses,
#: which EI excludes via ``!bae.Initial``. Self-apply gating reproduces
Expand Down Expand Up @@ -880,7 +881,8 @@ def add_instant(source: int, skill_id: int, time_ms: int, icd: int = 50) -> None
and elite_specs.get(event.target_agent_id) is EliteSpec.WEAVER
)
or (
event.skill_id in _BUFF_GAIN_SELF_ONLY
event.kind == "apply"
and event.skill_id in _BUFF_GAIN_SELF_ONLY
and event.source_agent_id != event.target_agent_id
)
or (
Expand Down
31 changes: 31 additions & 0 deletions libs/gw2_analytics/tests/test_rotation.py
Original file line number Diff line number Diff line change
Expand Up @@ -1568,3 +1568,34 @@ def casts(**kwargs: Any) -> list[int]:
assert casts() == [5492]
assert casts(elite_specs={7: EliteSpec.TEMPEST}) == [5492]
assert casts(elite_specs={7: EliteSpec.WEAVER}) == [43470]


def test_berserk_loss_is_booked_as_berserk_end() -> None:
"""EI books ``BerserkEndSkill`` (-41) when the Berserk buff is fully removed."""
origin = 42_000_000

def casts(*events: Event) -> list[int]:
return [
cast.skill_id
for cast in build_skill_rotation(list(events), duration_ms=1_000, start_time_ms=origin)
]

gain = BoonApplyEvent(
time_ms=origin + 100,
source_agent_id=7,
target_agent_id=7,
skill_id=29502,
duration_ms=5_000,
stacks=1,
)
end = BoonApplyEvent(
time_ms=origin + 5_100,
source_agent_id=0,
target_agent_id=7,
skill_id=29502,
duration_ms=0,
stacks=0,
kind="remove_all",
)
assert casts(gain) == [30435]
assert casts(gain, end) == [30435, -41]
Loading