Skip to main content

wowlab_engine_combat/handler/orchestration/
reset.rs

1use wowlab_engine_ports::SimContext;
2use wowlab_types::sim::{PlayerResetFlags, PositionedActorRef, PullId, SimTime};
3
4use super::super::{
5    CombatHandler,
6    reset::{
7        reset_cooldowns, reset_guardians_between_pulls, reset_player_auras, reset_resources,
8        set_precombat_aura_stacks,
9    },
10};
11use crate::{
12    context::HookCtxRequest,
13    systems::{apply_aura, initialize_all_spell_costs},
14};
15
16impl CombatHandler {
17    pub(super) fn apply_player_reset(
18        &mut self,
19        flags: PlayerResetFlags,
20        next_pull: PullId,
21        now: SimTime,
22        ctx: &mut SimContext,
23    ) -> bool {
24        let mut target_precombat_pending = false;
25
26        if flags.contains(PlayerResetFlags::RESOURCES) {
27            reset_resources(&self.program, &mut self.instance);
28            self.last_resource_sync = now;
29        }
30
31        if flags.contains(PlayerResetFlags::COOLDOWNS) {
32            reset_cooldowns(&self.program, &mut self.instance, now);
33        }
34
35        if flags.contains(PlayerResetFlags::AURAS) {
36            reset_player_auras(&self.program, &mut self.instance);
37
38            for index in 0..self.program.precombat_auras.len() {
39                let aura = self
40                    .program
41                    .precombat_auras
42                    .get(index)
43                    .copied()
44                    .expect("bounded precombat aura index");
45
46                if self.program.aura(aura).on == wowlab_types::sim::AuraOn::Target {
47                    target_precombat_pending = true;
48                    continue;
49                }
50
51                self.with_hook_ctx(
52                    &mut *ctx.telemetry,
53                    HookCtxRequest::for_optional_target(now, None),
54                    |hook| apply_aura(hook, aura),
55                );
56            }
57
58            for index in 0..self.program.talent_aura_stacks.len() {
59                let (aura, count) = self
60                    .program
61                    .talent_aura_stacks
62                    .get(index)
63                    .copied()
64                    .expect("bounded talent aura index");
65
66                if self.program.aura(aura).on == wowlab_types::sim::AuraOn::Target {
67                    target_precombat_pending = true;
68                    continue;
69                }
70
71                set_precombat_aura_stacks(&self.program, &mut self.instance, aura, count, None);
72            }
73
74            initialize_all_spell_costs(&self.program, &mut self.instance);
75        }
76
77        if flags.contains(PlayerResetFlags::GUARDIANS) {
78            reset_guardians_between_pulls(&self.program, &mut self.instance);
79        }
80
81        if flags.contains(PlayerResetFlags::POSITION) {
82            let definition = self.program.config.encounter.definition();
83            let Some(transform) = definition
84                .pulls
85                .get(next_pull.as_usize())
86                .map(|pull| pull.player_start_transform)
87                .map(|transform| transform.unwrap_or(definition.initial_player_transform))
88            else {
89                return target_precombat_pending;
90            };
91
92            if let Err(error) =
93                self.instance
94                    .relocate_actor(PositionedActorRef::Player, transform, now)
95            {
96                self.record_script_error(
97                    next_pull,
98                    format!("player reset position failed: {error}"),
99                );
100            }
101        }
102
103        target_precombat_pending
104    }
105}