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(Copy, 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(Copy, 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 let tool_stats = get_tool_stats(data, self.static_data.ability_info);
78
79 data.updater.insert(
80 data.entity,
81 self.static_data
82 .melee_constructor
83 .create_melee(precision_mult, tool_stats),
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(
108 data,
109 self.timer,
110 Some(data.stats.recovery_speed_modifier),
111 );
112 } else {
113 end_melee_ability(data, &mut update);
115 }
116 }
117 },
118 _ => {
119 end_melee_ability(data, &mut update);
121 },
122 }
123
124 update
125 }
126}