veloren_common/states/
riposte_melee.rs1use crate::{
2 combat,
3 comp::{CharacterState, MeleeConstructor, StateUpdate, character_state::OutputEvents},
4 states::{
5 behavior::{CharacterBehavior, JoinData},
6 utils::*,
7 },
8};
9use serde::{Deserialize, Serialize};
10use std::time::Duration;
11
12#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
14pub struct StaticData {
15 pub buildup_duration: Duration,
17 pub swing_duration: Duration,
19 pub recover_duration: Duration,
21 pub whiffed_recover_duration: Duration,
23 pub block_strength: f32,
26 pub melee_constructor: MeleeConstructor,
28 pub ability_info: AbilityInfo,
30}
31
32#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
33pub struct Data {
34 pub static_data: StaticData,
37 pub timer: Duration,
39 pub stage_section: StageSection,
41 pub exhausted: bool,
43 pub whiffed: bool,
45}
46
47impl CharacterBehavior for Data {
48 fn behavior(&self, data: &JoinData, output_events: &mut OutputEvents) -> StateUpdate {
49 let mut update = StateUpdate::from(data);
50
51 handle_orientation(data, &mut update, 1.0, None);
52 handle_move(data, &mut update, 0.7);
53 handle_jump(data, output_events, &mut update, 1.0);
54 handle_interrupts(data, &mut update, output_events);
55
56 match self.stage_section {
57 StageSection::Buildup => {
58 if let CharacterState::RiposteMelee(c) = &mut update.character {
59 if self.timer < self.static_data.buildup_duration {
60 c.timer = tick_attack_or_default(data, self.timer, None);
62 } else {
63 c.timer = Duration::default();
66 c.stage_section = StageSection::Recover;
67 }
68 }
69 },
70 StageSection::Action => {
71 if !self.exhausted {
72 if let CharacterState::RiposteMelee(c) = &mut update.character {
73 c.exhausted = true;
74 }
75
76 let precision_mult = combat::compute_precision_mult(data.inventory, data.msm);
77
78 data.updater.insert(
79 data.entity,
80 self.static_data
81 .melee_constructor
82 .clone()
83 .create_melee(precision_mult, self.static_data.ability_info),
84 );
85 } else if self.timer < self.static_data.swing_duration {
86 if let CharacterState::RiposteMelee(c) = &mut update.character {
88 c.timer = tick_attack_or_default(data, self.timer, None);
89 }
90 } else {
91 if let CharacterState::RiposteMelee(c) = &mut update.character {
93 c.timer = Duration::default();
94 c.stage_section = StageSection::Recover
95 }
96 }
97 },
98 StageSection::Recover => {
99 if let CharacterState::RiposteMelee(c) = &mut update.character {
100 let recover_duration = if c.whiffed {
101 self.static_data.whiffed_recover_duration
102 } else {
103 self.static_data.recover_duration
104 };
105 if self.timer < recover_duration {
106 c.timer = tick_attack_or_default(data, self.timer, None);
108 } else {
109 end_melee_ability(data, &mut update);
111 }
112 }
113 },
114 _ => {
115 end_melee_ability(data, &mut update);
117 },
118 }
119
120 update
121 }
122}