Skip to content

Monk: Fists of Fury channel rolls the attack table itself, so a missed cast discards all ticks #11879

Description

@RexZep-dev

Summary

fists_of_fury_t is a channel with no direct damage (attack_power_mod.direct = 0);
all of its damage comes from the tick action fists_of_fury_damage, which rolls
the attack table on its own. The channel itself keeps may_miss / may_dodge /
may_parry at their defaults, so when the cast is missed or dodged the channel
never starts and every tick is lost. The ticks that do happen are then rolled
again individually, so Fists of Fury is penalised twice for the same miss chance.

Where

engine/class_modules/monk/sc_monk.cpp, constructor of fists_of_fury_t
(branch midnight, checked at 66096c1):

may_combo_strike        = true;
attack_power_mod.direct = 0;
channeled               = true;

Reproduction

monk="FofRepro"
level=20
race=pandaren
role=attack
spec=windwalker
talents=C0QAQnG51S19isUJoJoTeJ/IKDAMDYAAAAAAAAAAAAAggZ2wAAAAAYCAAAgZAAAAAAAAAAAADA
main_hand=,id=9485,bonus_id=6710,drop_level=20
off_hand=,id=9485,bonus_id=6710,drop_level=20
target_level=38
max_time=300
actions=auto_attack
actions+=/fists_of_fury
actions+=/tiger_palm

A high-level target just makes the miss chance large enough to see clearly;
the mechanism applies to any miss or dodge on the cast.

Combat log (iterations=1, log=1), build 1210-01 / midnight c1935b9:

1.004 Player 'FofRepro' performs Action 'fists_of_fury' (113656)
1.004 Player 'FofRepro' Action 'fists_of_fury' (113656) hits Enemy 'Fluffy_Pillow' for 0.000000 physical damage (miss)
1.004 Target Enemy 'Fluffy_Pillow' avoids Player 'FofRepro' Action 'fists_of_fury' (113656) (miss)
      -> no ticks follow
25.683 Player 'FofRepro' performs Action 'fists_of_fury' (113656)
25.683 Player 'FofRepro' Action 'fists_of_fury' (113656) hits Enemy 'Fluffy_Pillow' for 0.000000 physical damage (hit)
25.683 Player 'FofRepro' Action 'fists_of_fury' (113656) ticks (0 of 4) Enemy 'Fluffy_Pillow'
25.683 Player 'FofRepro' Action 'fists_of_fury_damage' (117418) hits Enemy 'Fluffy_Pillow' for 175.686444 physical damage (hit)
...

Numbers

Same profile, full run:

casts ticks ticks per cast tick miss rate damage per cast
current 13.0 36 2.8 22.5% 350
cast cannot miss 12.9 64 5.0 22.6% 633

The channel has 5 ticks. 36 ticks from 13 casts means only ~55% of channels
started: the cast itself was missed or dodged ~45% of the time (22.5% + 22.5%
at this level difference), and each surviving tick still missed 22.5% on its own.

In-game evidence

Warcraft Logs events from two level-20 Windwalkers in dungeons with high-level
mobs, split by spell: the cast (113656) and the damage ticks (117418).

The cast itself does show up as avoided in-game — about 20% of casts
(3 of 16 and 6 of 29; miss, dodge and parry). But the channel keeps going:
against a single target, a cast that was avoided was followed by 5 and 4
damage ticks within the next 5 seconds, the same as a cast that landed (5).
So in the game an avoided cast does not cost any ticks; in SimC it costs all of them.

Expected

The channel should not roll hit itself, since its ticks already do:

may_miss = may_dodge = may_parry = false;

With that line added to the constructor, every cast produces its 5 ticks and the
per-tick miss rate is unchanged (second row above).

Impact

The loss scales with miss and dodge chance, so it is small against a +3 dummy
and large at bigger level differences — at +18 it roughly halves Fists of Fury.

Related

#11875 — chi refund on miss in the same module (separate bug).

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions