Skip to main content

wowlab_engine_content/hooks/fury_warrior/
handler.rs

1use wowlab_engine_combat::CombatHandler;
2use wowlab_engine_ports::{HandlerParams, SimContext, SpecAction};
3
4
5use crate::{
6    generated::specs::fury_warrior::{AURA_SUDDEN_DEATH, SPELL_EXECUTE},
7    hooks::shared::warrior::sync_execute_gate,
8};
9
10use super::config::register_fury;
11
12/// Maintains Execute's health and Sudden Death gate.
13#[derive(Debug)]
14// #t(rust_similar_structs) Arms and Fury retain separate specialization handler ownership and hook implementations
15pub(crate) struct FuryHandler {
16    inner: CombatHandler,
17    execute_threshold: f64,
18}
19
20impl FuryHandler {
21    /// Finishes the specialization handler from the shared-content composition stage.
22    pub(crate) fn try_new(
23        parts: crate::composition::ContentHandlerParts,
24        params: &HandlerParams<'_>,
25    ) -> Result<Self, wowlab_engine_ports::EngineError> {
26        let mut parts = parts;
27        let built = parts.draft_mut();
28        let cfg = register_fury(built, params)?;
29
30        let built = parts.finalize()?;
31
32        Ok(Self {
33            inner: CombatHandler::from_built(built),
34            execute_threshold: cfg.execute_threshold,
35        })
36    }
37}
38
39crate::hooks::define_spec_handler! {
40impl FuryHandler(self, inner) {
41    fn on_sim_start(&mut self, ctx: &mut SimContext) {
42        self.inner.on_sim_start(ctx);
43        sync_execute_gate(
44            &mut self.inner,
45            self.execute_threshold,
46            AURA_SUDDEN_DEATH,
47            SPELL_EXECUTE,
48            ctx,
49        );
50    }
51
52    fn on_player_ready(&mut self, ctx: &mut SimContext) -> Option<SpecAction> {
53        sync_execute_gate(
54            &mut self.inner,
55            self.execute_threshold,
56            AURA_SUDDEN_DEATH,
57            SPELL_EXECUTE,
58            ctx,
59        );
60        self.inner.on_player_ready(ctx)
61    }
62
63    fn on_cast_complete(&mut self, event: wowlab_engine_ports::Event, ctx: &mut SimContext) {
64        self.inner.on_cast_complete(event, ctx);
65        sync_execute_gate(
66            &mut self.inner,
67            self.execute_threshold,
68            AURA_SUDDEN_DEATH,
69            SPELL_EXECUTE,
70            ctx,
71        );
72    }
73
74    fn on_spell_impact(&mut self, impact_id: wowlab_engine_ports::PendingImpactBinding, ctx: &mut SimContext) {
75        self.inner.on_spell_impact(impact_id, ctx);
76    }
77
78}
79delegate {
80            fn on_aura_tick(&mut self, event: wowlab_engine_ports::AuraEventRef, ctx: &mut SimContext);
81            fn on_aura_expire(&mut self, event: wowlab_engine_ports::AuraEventRef, ctx: &mut SimContext);
82            fn on_auto_attack(&mut self, source: wowlab_types::sim::ActorId, target: wowlab_types::sim::EnemyIdx, ctx: &mut SimContext);
83            fn on_cooldown_ready(&mut self, spell: wowlab_engine_ports::ScheduledSpellBinding, ctx: &mut SimContext);
84            fn flush_scheduled(&mut self, push: &mut dyn FnMut(wowlab_engine_ports::Event));
85            fn reset(&mut self);
86            fn total_damage(&self) -> f64;
87            fn cast_time_ms(&self, spell: wowlab_engine_ports::ScheduledSpellBinding, empower_rank: u8) -> u32;
88            fn introspect(&self) -> wowlab_types::game::SpecIntrospection;
89            fn paperdoll(&self) -> Option<wowlab_engine_ports::Paperdoll>;
90            fn attach_decision_trace(
91                &mut self,
92                sink: std::sync::Arc<dyn wowlab_engine_ports::DecisionTraceSink>,
93            );
94}
95}