wowlab_engine_combat/systems/auras/
deferred.rs1use super::{
2 ActorId, EffectExecution, EnemyIdx, HookCtx, MAX_DEFERRED_WORK_ITEMS,
3 execute_effect_range_for_actor, execute_proc_effect_range_for_actor,
4 fire_aura_application_procs,
5};
6
7pub(crate) fn drain_deferred_work(ctx: &mut HookCtx<'_>) {
9 let mut processed = 0;
10
11 while let Some(work) = ctx.instance.runtime.deferred_work.pop_next() {
12 processed += 1;
13
14 if processed > MAX_DEFERRED_WORK_ITEMS {
15 ctx.instance.runtime.deferred_work.clear();
16 break;
17 }
18
19 match work {
20 crate::state::DeferredWork::Effect(program) => {
21 for _ in 0..program.repeat {
22 let target = program
23 .target
24 .or_else(|| ctx.instance.current_target())
25 .unwrap_or(EnemyIdx::PRIMARY);
26 let mut combat_ctx = ctx.combat_ctx_with_source(program.source, target);
27
28 let execution = EffectExecution {
29 range: program.effects,
30 profile_spell_id: program.profile_spell_id,
31 profile_action: program.profile_action,
32 flags: program.flags,
33 };
34
35 if program.originating_proc_driver_spell_id == 0 {
36 execute_effect_range_for_actor(
37 &mut combat_ctx,
38 execution,
39 program.effect_target,
40 );
41 } else {
42 execute_proc_effect_range_for_actor(
43 &mut combat_ctx,
44 execution,
45 program.effect_target,
46 program.originating_proc_driver_spell_id,
47 );
48 }
49 }
50 }
51 crate::state::DeferredWork::AuraApplication(event) => {
52 let target = match event.affected {
53 ActorId::Enemy(target) => target,
54 _ => event
55 .target
56 .or_else(|| ctx.instance.current_target())
57 .unwrap_or(EnemyIdx::PRIMARY),
58 };
59 let mut combat_ctx = ctx.combat_ctx_with_source(event.source, target);
60
61 fire_aura_application_procs(&mut combat_ctx, event);
62 }
63 crate::state::DeferredWork::AuraExpire(expiry) => {
64 let aura = ctx.program.auras[expiry.aura.as_usize()];
66
67 if let Some(hook_fn) = aura.on_expire {
68 let mut hook_ctx = HookCtx::new(
69 crate::context::HookCtxServices {
70 program: ctx.program,
71 instance: ctx.instance,
72 sink: ctx.sink,
73 rng: ctx.rng,
74 },
75 crate::context::HookCtxRequest::for_optional_target(ctx.now, expiry.target)
76 .with_source(expiry.key.source()),
77 )
78 .with_driver_spell(aura.aura_id)
79 .with_effect_target(expiry.key.affected());
80
81 hook_fn(&mut hook_ctx);
82 }
83 }
84 }
85 }
86}