Skip to main content

wowlab_engine_combat/systems/damage_pipeline/
snapshot.rs

1use wowlab_types::sim::AuraKey;
2
3use super::{
4    BoundDamageRequest, DamageFlags, DamageRequest, WeaponDamageInput,
5    dispatch::run_single_hit,
6    setup::{DamageSetup, DamageSnapshot, SnapshotDamageContext, SnapshotDamageEvent},
7};
8use crate::{context::CombatCtx, state::LocalAuraIdx};
9
10#[derive(Clone, Copy, Debug)]
11pub(crate) enum SnapshotPower {
12    Attack,
13    Spell,
14}
15
16#[derive(Clone, Copy, Debug)]
17pub(crate) struct SnapshotDamageInput {
18    pub(crate) binding: crate::state::program::DamageRequestBinding,
19    pub(crate) effect: crate::state::DamageEffectRef,
20    pub(crate) coefficient: f64,
21    pub(crate) flags: DamageFlags,
22    pub(crate) power: SnapshotPower,
23}
24
25pub(crate) fn read_aura_snapshot(
26    program: &crate::state::CombatProgram,
27    instance: &crate::state::CombatInstance,
28    local: LocalAuraIdx,
29    key: AuraKey,
30) -> Option<DamageSnapshot> {
31    let a = program.buffer_aura(instance, local, key)?;
32
33    if a.snapshot_has == 0 {
34        return None;
35    }
36
37    Some(DamageSnapshot {
38        ap: a.snapshot_ap,
39        sp: a.snapshot_sp,
40        crit_pct: a.snapshot_crit,
41        vers_pct: a.snapshot_vers,
42        mastery_mult: a.snapshot_mastery_mult,
43        damage_mult: a.snapshot_damage_mult,
44    })
45}
46
47pub(crate) fn deal_damage_with_snapshot(
48    ctx: &mut CombatCtx<'_>,
49    input: SnapshotDamageInput,
50    snap: &DamageSnapshot,
51) -> (f64, bool) {
52    let SnapshotDamageInput {
53        binding,
54        effect,
55        coefficient,
56        flags,
57        power,
58    } = input;
59    let spell_id = effect.spell_id;
60    let target = ctx.target;
61    let setup = DamageSetup::from_snapshot_for(
62        SnapshotDamageContext::new(
63            ctx.program,
64            ctx.instance,
65            SnapshotDamageEvent {
66                source: ctx.source,
67                target,
68                now: ctx.now,
69            },
70        ),
71        binding,
72        effect,
73        flags,
74        snap,
75    );
76
77    let power = match power {
78        SnapshotPower::Attack => snap.ap,
79        SnapshotPower::Spell => snap.sp,
80    };
81
82    let request = DamageRequest {
83        effect,
84        geometry_effect: effect,
85        source_position: None,
86        destination: None,
87        profile_spell_id: spell_id,
88        base_points: None,
89        coef: coefficient,
90        power,
91        weapon: WeaponDamageInput::none(),
92        flags: flags | DamageFlags::PERIODIC,
93    };
94    let request = BoundDamageRequest::new(request, binding);
95
96    run_single_hit(ctx, target, &setup, &request, 1.0)
97}