Skip to main content

wowlab_engine_combat/systems/damage_pipeline/
mod.rs

1//! The damage pipeline: request types, setup resolution, single-hit rolls, and dispatch.
2
3mod absorbs;
4pub(crate) mod api;
5mod dispatch;
6mod incoming;
7mod leech;
8mod setup;
9mod snapshot;
10mod weapon;
11
12#[cfg(test)]
13use wowlab_engine_gamedata::ResolvedGameData;
14#[cfg(test)]
15use wowlab_engine_telemetry::{DamageEvent, DamageEventFlags, TelemetrySink};
16#[cfg(test)]
17use wowlab_types::sim::{ActorId, EnemyIdx, SpellIdx};
18
19#[cfg(test)]
20use crate::context::CombatCtx;
21
22#[cfg(test)]
23const FINALIZED_FIXTURE_DAMAGE_IDENTITY: &str =
24    "test damage identity belongs to the finalized fixture";
25
26#[rustfmt::skip]
27pub(super) use absorbs::resolve_outgoing_absorbs;
28#[rustfmt::skip]
29pub(in crate::systems) use api::deal_damage_ap_with_weapon;
30#[rustfmt::skip]
31pub(crate) use api::{
32    DamageFlags, DamagePayload, ProfiledDamageDef, damage_flags_from_binding, damage_flags_from_data, damage_flags_from_local,
33    deal_bound_damage_ap, deal_damage_ap_at, deal_damage_base, deal_damage_def, deal_bound_damage_sp, deal_damage_sp_at,
34    deal_effect_damage_ap, deal_bound_effect_damage_ap_with_geometry, deal_effect_damage_base,
35    deal_effect_damage_sp, deal_effect_damage_sp_with_geometry, deal_bound_profiled_damage_def,
36    deal_profiled_damage_def_at, deal_residual_damage, deal_bound_resolved_damage,
37    resolve_spell_impact_flags,
38};
39#[rustfmt::skip]
40pub(super) use api::{
41    BoundDamageRequest, DamageRequest, emit_damage_telemetry, finalize_damage, finalize_damage_with,
42    reported_damage_spell_id,
43};
44
45/// Deals fixture damage through a finalized diagnostic identity.
46///
47/// # Panics
48///
49/// Panics when the fixture did not register the requested diagnostic damage identity.
50#[cfg(test)]
51pub fn deal_damage_ap(ctx: &mut CombatCtx<'_>, payload: DamagePayload) -> (f64, bool) {
52    let effect = crate::state::DamageEffectRef::new(payload.spell_id, 1);
53    let binding = ctx
54        .program
55        .damage
56        .diagnostic_bind_request(effect, effect, payload.resolved_profile_spell_id())
57        .expect(FINALIZED_FIXTURE_DAMAGE_IDENTITY);
58
59    deal_bound_damage_ap(ctx, binding, payload)
60}
61
62#[cfg(test)]
63pub(super) fn deal_damage_sp(ctx: &mut CombatCtx<'_>, payload: DamagePayload) -> (f64, bool) {
64    let effect = crate::state::DamageEffectRef::new(payload.spell_id, 1);
65    let binding = ctx
66        .program
67        .damage
68        .diagnostic_bind_request(effect, effect, payload.resolved_profile_spell_id())
69        .expect(FINALIZED_FIXTURE_DAMAGE_IDENTITY);
70
71    deal_bound_damage_sp(ctx, binding, payload)
72}
73
74#[cfg(test)]
75pub(super) fn deal_effect_damage_ap_with_geometry(
76    ctx: &mut CombatCtx<'_>,
77    effect: crate::state::DamageEffectRef,
78    geometry_effect: crate::state::DamageEffectRef,
79    coefficient: f64,
80    flags: DamageFlags,
81) -> (f64, bool) {
82    let binding = ctx
83        .program
84        .damage
85        .diagnostic_bind_request(effect, geometry_effect, effect.spell_id)
86        .expect(FINALIZED_FIXTURE_DAMAGE_IDENTITY);
87
88    deal_bound_effect_damage_ap_with_geometry(
89        ctx,
90        binding,
91        effect,
92        geometry_effect,
93        coefficient,
94        flags,
95    )
96}
97
98#[cfg(test)]
99pub(super) fn deal_profiled_damage_def(
100    ctx: &mut CombatCtx<'_>,
101    effect: crate::state::DamageEffectRef,
102    profile_spell_id: u32,
103    base_points: Option<f64>,
104    damage: crate::state::RuntimeDamageDef,
105    flags: DamageFlags,
106) -> (f64, bool) {
107    let binding = ctx
108        .program
109        .damage
110        .diagnostic_bind_request(effect, effect, profile_spell_id)
111        .expect(FINALIZED_FIXTURE_DAMAGE_IDENTITY);
112
113    deal_bound_profiled_damage_def(
114        ctx,
115        ProfiledDamageDef {
116            binding,
117            effect,
118            geometry_effect: effect,
119            profile_spell_id,
120            base_points,
121            def: damage,
122            flags,
123            source_position: None,
124            destination: None,
125        },
126    )
127}
128#[rustfmt::skip]
129pub(crate) use incoming::{IncomingDamage, deal_incoming_damage};
130#[rustfmt::skip]
131pub(crate) use setup::{
132    DamageSnapshot, dynamic_base_powers, dynamic_stamina, read_player_stats_for_damage,
133    spell_modifiers::{
134        SpellModifierEffect, SpellModifierProfile, SpellModifierQuery, spell_scoped_mods_for,
135    },
136};
137#[cfg(feature = "rotation-optimizations")]
138pub(crate) use setup::static_damage_buff_projection;
139#[rustfmt::skip]
140pub(crate) use snapshot::{
141    SnapshotDamageInput, SnapshotPower, deal_damage_with_snapshot, read_aura_snapshot,
142};
143#[rustfmt::skip]
144pub(super) use weapon::WeaponDamageInput;
145#[rustfmt::skip]
146pub(crate) use weapon::{current_spell_power, typed_attack_power, typed_attack_power_with};
147
148#[cfg(test)]
149#[path = "tests.rs"]
150mod tests;