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 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}