wowlab_engine_combat/systems/damage_pipeline/
snapshot.rs1use 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}