Skip to main content

wowlab_engine_combat/
lib.rs

1#![expect(
2    clippy::multiple_crate_versions,
3    reason = "the workspace dependency graph currently includes independently versioned transitive dependencies"
4)]
5#![expect(
6    clippy::redundant_feature_names,
7    // #t(rust_duplicate_strings) Rust attributes require a literal reason at the declaration they govern.
8    reason = "the cross-crate test-support capability name is mandated by the shared fixture contract"
9)]
10
11//! Combat system for the `WoW` Lab simulation engine.
12//!
13
14mod builder;
15mod context;
16mod handler;
17mod keys;
18mod pipeline;
19mod state;
20mod systems;
21mod targeting;
22#[cfg(any(test, feature = "test-support"))]
23pub mod test_support;
24mod travel;
25
26#[rustfmt::skip]
27pub use builder::{
28    BuilderError, CombatBuildError, validated_channel_tick_count, validated_max_stacks,
29    validated_milliseconds, validated_nonnegative,
30};
31pub use builder::{
32    aura_builder::{AuraDefinitionDraft, PeriodicDamageDataInput},
33    auto_attack_builder::AutoAttackDefinitionDraft,
34    built::BuiltCombatSystem,
35    combat_builder::{CombatSystemBuilder, RppmScalingOptions},
36    impact_effect_proc_builder::ImpactEffectProcDefinition,
37    spell_builder::draft::SpellDefinitionDraft,
38};
39pub use wowlab_types::combat::PeriodicDamageMode;
40#[rustfmt::skip]
41pub use context::{
42    FreeActionSource, HookCtx, HookCtxRequest, HookCtxServices,
43};
44pub use context::{
45    combat_ctx::{CombatCtx, CombatView, HookView},
46    damage::DamageOutcome,
47    hook::{AuraOps, CooldownOps, DamageOps, GuardianOps, ProcOps, ResourceOps, SchedulingOps},
48};
49#[rustfmt::skip]
50pub use handler::CombatHandler;
51#[rustfmt::skip]
52pub use pipeline::process_cast;
53#[rustfmt::skip]
54pub use state::buff_effect::{
55    BuffEffect, BuffTotals, MAX_AURA_BUFF_EFFECTS, try_push_effect,
56};
57pub use state::{
58    combat_state::{CombatState, config::AttackPosition},
59    config::BaseStats,
60    damage::{
61        DamageEffectRef, DamageReplication, DamageSource, HealthThresholdDirection,
62        RuntimeDamageDef, WeaponApType,
63    },
64    defs::{
65        aura::{AuraData, AuraTickBehavior, DynamicTickAction},
66        drivers::{
67            DriverSpellModifier, DriverSpellModifierResult, PassiveDriverEffect, PeriodicDriver,
68            WeaponEnchantBinding,
69        },
70        guardians::{
71            GuardianAbility, GuardianActionFn, GuardianEvent, GuardianHandle, GuardianSpec,
72        },
73        periodic::{PeriodicData, PeriodicKind},
74    },
75};
76#[rustfmt::skip]
77pub use state::defs::procs::{
78    AccumulatingImpactProc, ImpactActorFilter, ImpactChanceScale, ImpactEvent, ImpactProc,
79    ImpactProcFn, ImpactSource, LandedImpactEvent, LandedImpactProc, LandedImpactProcFn,
80    ProcDriver, ProcEventKind, ProcHitMask, ProcPhaseMask, ProcPolicy, ProcProvenance,
81    ProcTriggerSide, ResourceGainEvent, ResourceGainProc, SwingEvent, SwingHand, SwingReplacement,
82};
83pub use state::{
84    LocalAuraIdx, LocalRppmIdx, LocalSpellIdx, LocalThresholdIdx,
85    defs::{
86        pets::{PetAbility, PetActionBar, PetResourceModel},
87        spell::{
88            CastHookFn, EmpowerReleaseAdjustment, MAX_AURA_APPLICATION_EXCLUSIONS, ResourcePool,
89            SpellEffectData, SpellEffectRange,
90        },
91    },
92    ground_effect::GroundEffectSpec,
93    resource::ResourceGainSource,
94};
95pub use wowlab_engine_rng::{RppmTracker, ThresholdTracker};
96#[rustfmt::skip]
97pub use systems::auras::apply::{apply_aura, apply_aura_with_duration};
98pub use systems::{
99    auras::{
100        expire::{expire_aura, expire_aura_by_id},
101        stacks::{extend_aura, is_aura_active},
102    },
103    buffs::accumulate_buffs,
104    channel::{clip_active_channel, process_channel_tick_for},
105    damage_pipeline::api::{DamageFlags, DamagePayload, deal_damage_ap},
106    mastery::{MasteryCtx, MasteryFn, no_crit_damage, no_damage_bonus},
107    periodic::tick::process_single_aura_tick_for,
108    resources::set_primary_resource_base_regen,
109    spell_gates::set_spell_gate,
110};
111/// Generates a smoke test that verifies `build_combat_system` does not panic with default inputs.
112#[macro_export]
113macro_rules! smoke_test {
114    ($build_fn:path) => {
115        #[cfg(test)]
116        mod tests {
117            use super::*;
118
119            #[googletest::gtest]
120            fn build_combat_system_does_not_panic() -> googletest::Result<()> {
121                let stats = wowlab_engine_ports::CombatStats::default();
122                let encounter = wowlab_engine_ports::test_support::introspection_fixture(300.0)
123                    .expect("valid smoke-test encounter proof");
124                let game_data =
125                    wowlab_engine_ports::test_support::introspection_game_data(&encounter);
126                let rotation = wowlab_types::sim::Rotation::empty();
127                let params = wowlab_engine_ports::HandlerParams {
128                    game_data,
129                    rotation: &rotation,
130                    stats: &stats,
131                    talent_selections: &[],
132                    encounter: &encounter,
133                    fight_duration_secs: encounter.fight_duration_secs(),
134                    equipped_items: &[],
135                    set_bonus_auras: &[],
136                    bloodlust: false,
137                    pre_pot_tempered: false,
138                    flask: false,
139                    augment_rune: false,
140                    race: wowlab_types::game::RaceId::Human,
141                    weapon_enchant_procs: &[],
142                    bugs: wowlab_engine_ports::BugSettings::default(),
143                    cast_latency: wowlab_engine_ports::CastLatency::default(),
144                    raid_events: &[],
145                    external_buffs: &[],
146                }
147                .validate()
148                .expect("valid handler params");
149                let _built = $build_fn(&params);
150                Ok(())
151            }
152        }
153    };
154}