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    state::LocalAuraIdx,
14    systems::{apply_aura, sync_spell_costs},
15};
16
17impl CombatHandler {
18    pub(super) fn apply_player_reset(
19        &mut self,
20        flags: PlayerResetFlags,
21        next_pull: PullId,
22        now: SimTime,
23        ctx: &mut SimContext,
24    ) -> bool {
25        let mut target_precombat_pending = false;
26
27        if flags.contains(PlayerResetFlags::RESOURCES) {
28            reset_resources(&mut self.state, &mut self.buf);
29            self.last_resource_sync = now;
30        }
31
32        if flags.contains(PlayerResetFlags::COOLDOWNS) {
33            reset_cooldowns(&mut self.state, &mut self.buf);
34        }
35
36        if flags.contains(PlayerResetFlags::AURAS) {
37            reset_player_auras(&mut self.buf);
38            let precombat: Vec<LocalAuraIdx> = self.state.defs.precombat_auras.clone();
39
40            for aura in precombat {
41                if self.state.aura(aura).on == wowlab_types::sim::AuraOn::Target {
42                    target_precombat_pending = true;
43                    continue;
44                }
45
46                self.with_hook_ctx(
47                    &mut *ctx.telemetry,
48                    HookCtxRequest::for_optional_target(now, None),
49                    |hook| apply_aura(hook, aura),
50                );
51            }
52
53            let stacks = self.state.defs.talent_aura_stacks.clone();
54
55            for (aura, count) in stacks {
56                if self.state.aura(aura).on == wowlab_types::sim::AuraOn::Target {
57                    target_precombat_pending = true;
58                    continue;
59                }
60
61                set_precombat_aura_stacks(&self.state, &mut self.buf, aura, count, None);
62            }
63
64            sync_spell_costs(&self.state, &mut self.buf);
65        }
66
67        if flags.contains(PlayerResetFlags::GUARDIANS) {
68            reset_guardians_between_pulls(&mut self.state);
69        }
70
71        if flags.contains(PlayerResetFlags::POSITION) {
72            let definition = self.state.config.encounter.definition();
73            let Some(transform) = definition
74                .pulls
75                .get(next_pull.as_usize())
76                .map(|pull| pull.player_start_transform)
77                .map(|transform| transform.unwrap_or(definition.initial_player_transform))
78            else {
79                return target_precombat_pending;
80            };
81
82            if let Err(error) = self
83                .state
84                .relocate_actor(PositionedActorRef::Player, transform)
85            {
86                self.record_script_error(
87                    next_pull,
88                    format!("player reset position failed: {error}"),
89                );
90            }
91        }
92
93        target_precombat_pending
94    }
95}