wowlab_engine_combat/handler/orchestration/
reset.rs1use 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}