veloren_common/states/
boost.rs

1use crate::{
2    comp::{CharacterState, StateUpdate, character_state::OutputEvents},
3    states::{
4        behavior::{CharacterBehavior, JoinData},
5        utils::*,
6    },
7};
8use serde::{Deserialize, Serialize};
9use std::time::Duration;
10
11/// Separated out to condense update portions of character state
12#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)]
13pub struct StaticData {
14    pub movement_duration: Duration,
15    pub only_up: bool,
16    pub speed: f32,
17    pub max_exit_velocity: f32,
18    pub ability_info: AbilityInfo,
19}
20
21#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)]
22pub struct Data {
23    /// Struct containing data that does not change over the course of the
24    /// character state
25    pub static_data: StaticData,
26    /// Timer for each stage
27    pub timer: Duration,
28}
29
30impl CharacterBehavior for Data {
31    fn behavior(&self, data: &JoinData, output_events: &mut OutputEvents) -> StateUpdate {
32        let mut update = StateUpdate::from(data);
33
34        handle_move(data, &mut update, 1.0);
35        handle_orientation(data, &mut update, 10.0, None);
36
37        if self.timer < self.static_data.movement_duration {
38            // Movement
39            if self.static_data.only_up {
40                update.vel.0.z += self.static_data.speed * data.dt.0;
41            } else {
42                update.vel.0 += *data.inputs.look_dir * self.static_data.speed * data.dt.0;
43                let dir = Some(update.vel.to_dir());
44                handle_orientation(data, &mut update, 10.0, dir);
45            }
46            update.character = CharacterState::Boost(Data {
47                timer: tick_attack_or_default(data, self.timer, None),
48                ..*self
49            });
50        } else {
51            // Done
52            if input_is_pressed(data, self.static_data.ability_info.input) {
53                reset_state(self, data, output_events, &mut update);
54            } else {
55                update.vel.0 = update.vel.0.try_normalized().unwrap_or_default()
56                    * update
57                        .vel
58                        .0
59                        .magnitude()
60                        .min(self.static_data.max_exit_velocity);
61                end_ability(data, &mut update);
62            }
63        }
64
65        update
66    }
67}
68
69fn reset_state(
70    data: &Data,
71    join: &JoinData,
72    output_events: &mut OutputEvents,
73    update: &mut StateUpdate,
74) {
75    handle_input(
76        join,
77        output_events,
78        update,
79        data.static_data.ability_info.input,
80    );
81}