veloren_common/states/
music.rs

1use crate::{
2    comp::{CharacterState, StateUpdate, character_state::OutputEvents, controller::InputKind},
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    /// How long the state is playing for
15    pub play_duration: Duration,
16    /// Adjusts turning rate during the attack
17    pub ori_modifier: f32,
18    /// What key is used to press ability
19    pub ability_info: AbilityInfo,
20}
21
22#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)]
23pub struct Data {
24    /// Struct containing data that does not change over the course of the
25    /// character state
26    pub static_data: StaticData,
27    /// Timer for each stage
28    pub timer: Duration,
29    /// What section the character stage is in
30    pub stage_section: StageSection,
31    /// Whether the attack can deal more damage
32    pub exhausted: bool,
33}
34
35impl CharacterBehavior for Data {
36    fn behavior(&self, data: &JoinData, output_events: &mut OutputEvents) -> StateUpdate {
37        let mut update = StateUpdate::from(data);
38
39        handle_orientation(data, &mut update, self.static_data.ori_modifier, None);
40        handle_move(data, &mut update, 0.7);
41        handle_jump(data, output_events, &mut update, 1.0);
42
43        match self.stage_section {
44            StageSection::Action => {
45                if !self.exhausted {
46                    update.character = CharacterState::Music(Data {
47                        timer: Duration::default(),
48                        exhausted: true,
49                        ..*self
50                    });
51                } else if self.timer < self.static_data.play_duration {
52                    // Play
53                    update.character = CharacterState::Music(Data {
54                        timer: tick_attack_or_default(data, self.timer, None),
55                        ..*self
56                    });
57                } else {
58                    // Done
59                    if input_is_pressed(data, self.static_data.ability_info.input) {
60                        reset_state(self, data, output_events, &mut update);
61                    } else {
62                        end_ability(data, &mut update);
63                    }
64                }
65            },
66            _ => {
67                // If it somehow ends up in an incorrect stage section
68                end_ability(data, &mut update);
69            },
70        }
71
72        // At end of state logic so an interrupt isn't overwritten
73        if !input_is_pressed(data, self.static_data.ability_info.input)
74            && input_is_pressed(data, InputKind::Roll)
75        {
76            handle_input(data, output_events, &mut update, InputKind::Roll);
77        }
78
79        update
80    }
81}
82
83fn reset_state(
84    data: &Data,
85    join: &JoinData,
86    output_events: &mut OutputEvents,
87    update: &mut StateUpdate,
88) {
89    handle_input(
90        join,
91        output_events,
92        update,
93        data.static_data.ability_info.input,
94    );
95}