wowlab_engine_content/hooks/assassination_rogue/
poisons.rs1use wowlab_engine_combat::AuraOps as _;
2use wowlab_engine_combat::DamageOps as _;
3use wowlab_engine_combat::ResourceOps as _;
4use wowlab_engine_combat::{DamageFlags, HookCtx};
5use wowlab_engine_rng::proc_chance;
6use wowlab_types::constants::HUNDRED;
7
8use crate::generated::specs::assassination_rogue::{
9 AURA_AMPLIFYING_POISON_DEBUFF, AURA_DEADLY_POISON_DOT, AURA_DEATHMARK, AURA_ENVENOM,
10 AURA_KINGSBANE, AURA_KINGSBANE_RAMP, AURA_WOUND_POISON,
11};
12
13use super::config::sin_config;
14
15pub(super) fn proc_poisons(ctx: &mut HookCtx<'_>) {
16 let cfg = sin_config(ctx);
17 let envenom_bonus = if ctx.is_aura_active(AURA_ENVENOM) {
18 cfg.envenom_poison_bonus
19 } else {
20 0.0
21 };
22 let deadly_chance = (ctx.action_proc_chance(
23 crate::generated::specs::assassination_rogue::DAMAGE_AURA::DEADLY_POISON,
24 ) + envenom_bonus)
25 .clamp(0.0, 1.0);
26
27 if cfg.has_deadly_poison && proc_chance(ctx.rng(), deadly_chance) {
28 deal_deadly_poison(ctx);
29 }
30
31 let amplifying_chance = (ctx.action_proc_chance(
32 crate::generated::specs::assassination_rogue::DAMAGE_AURA::AMPLIFYING_POISON,
33 ) + envenom_bonus)
34 .clamp(0.0, 1.0);
35
36 if cfg.has_amplifying_poison && proc_chance(ctx.rng(), amplifying_chance) {
37 deal_amplifying_poison(ctx);
38 }
39
40 if ctx.is_aura_active(AURA_WOUND_POISON) {
41 let wound_chance = (ctx.action_proc_chance(
42 crate::generated::specs::assassination_rogue::DAMAGE_AURA::WOUND_POISON,
43 ) + envenom_bonus)
44 .clamp(0.0, 1.0);
45
46 if proc_chance(ctx.rng(), wound_chance) {
47 deal_wound_poison(ctx);
48 }
49 }
50}
51
52const DEATHMARK_LETHAL_EXECUTIONS: u32 = 2;
54const MID2_WOUND_POISON_EXECUTIONS: u32 = 2;
55
56fn lethal_executions(ctx: &HookCtx<'_>) -> u32 {
57 if ctx.is_aura_active(AURA_DEATHMARK) {
58 DEATHMARK_LETHAL_EXECUTIONS
59 } else {
60 1
61 }
62}
63
64fn ramp_kingsbane(ctx: &mut HookCtx<'_>) {
65 if ctx.is_aura_active(AURA_KINGSBANE) {
66 ctx.apply_aura(AURA_KINGSBANE_RAMP);
67 }
68}
69
70pub(super) fn deal_deadly_poison(ctx: &mut HookCtx<'_>) {
71 for _ in 0..lethal_executions(ctx) {
72 if ctx.is_aura_active(AURA_DEADLY_POISON_DOT) {
73 let coef = ctx.effect_ap_coefficient(crate::generated::specs::assassination_rogue::DAMAGE_EFFECT::DEADLY_POISON_INSTANT_DMG);
74
75 ctx.deal_damage_ap(
76 crate::generated::specs::assassination_rogue::DAMAGE_SPELL::DEADLY_POISON_INSTANT,
77 coef,
78 DamageFlags::empty(),
79 );
80 dashing_scoundrel(ctx);
81 }
82
83 ctx.apply_aura(AURA_DEADLY_POISON_DOT);
84 ramp_kingsbane(ctx);
85 }
86}
87
88pub(super) fn deal_amplifying_poison(ctx: &mut HookCtx<'_>) {
89 let coef = ctx.effect_ap_coefficient(
90 crate::generated::specs::assassination_rogue::DAMAGE_EFFECT::AMPLIFYING_POISON_DMG,
91 );
92
93 for _ in 0..lethal_executions(ctx) {
94 ctx.deal_damage_ap(
95 crate::generated::specs::assassination_rogue::DAMAGE_EFFECT::AMPLIFYING_POISON_DMG
96 .action(),
97 coef,
98 DamageFlags::empty(),
99 );
100 ctx.apply_aura(AURA_AMPLIFYING_POISON_DEBUFF);
101 ramp_kingsbane(ctx);
102 dashing_scoundrel(ctx);
103 }
104}
105
106fn deal_wound_poison(ctx: &mut HookCtx<'_>) {
107 let cfg = sin_config(ctx);
108 let tier_executions = if cfg.mid2_4pc {
109 MID2_WOUND_POISON_EXECUTIONS
110 } else {
111 1
112 };
113 let coefficient = ctx.effect_ap_coefficient(
114 crate::generated::specs::assassination_rogue::DAMAGE_EFFECT::WOUND_POISON_DAMAGE,
115 );
116
117 for _ in 0..lethal_executions(ctx) * tier_executions {
118 ctx.deal_damage_ap(
119 crate::generated::specs::assassination_rogue::DAMAGE_REPORTED::WOUND_POISON_DAMAGE,
120 coefficient,
121 DamageFlags::empty(),
122 );
123 ramp_kingsbane(ctx);
124 dashing_scoundrel(ctx);
125 }
126}
127
128fn dashing_scoundrel(ctx: &mut HookCtx<'_>) {
130 let cfg = sin_config(ctx);
131
132 if cfg.dashing_scoundrel_energy <= 0.0 || !ctx.is_aura_active(AURA_ENVENOM) {
133 return;
134 }
135
136 let crit = ctx.buf().player().crit / HUNDRED;
137
138 if proc_chance(ctx.rng(), crit) {
139 ctx.gain_resource(cfg.dashing_scoundrel_energy);
140 }
141}
142
143pub(super) fn seal_fate(ctx: &mut HookCtx<'_>) {
145 let cfg = sin_config(ctx);
146
147 if cfg.seal_fate_chance <= 0.0 {
148 return;
149 }
150
151 let crit = ctx.buf().player().crit / HUNDRED;
152
153 if !proc_chance(ctx.rng(), crit * cfg.seal_fate_chance) {
154 return;
155 }
156
157 ctx.gain_secondary_resource(cfg.seal_fate_cp);
158
159 if cfg.deal_fate_cp > 0.0 {
160 ctx.gain_secondary_resource(cfg.deal_fate_cp);
161 }
162}