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 let tool_stats = get_tool_stats(data, self.static_data.ability_info);
78
79 data.updater.insert(
80 data.entity,
81 self.static_data.melee_constructor.clone().create_melee(
82 precision_mult,
83 tool_stats,
84 self.static_data.ability_info,
85 ),
86 );
87 } else if self.timer < self.static_data.swing_duration {
88 if let CharacterState::RiposteMelee(c) = &mut update.character {
90 c.timer = tick_attack_or_default(data, self.timer, None);
91 }
92 } else {
93 if let CharacterState::RiposteMelee(c) = &mut update.character {
95 c.timer = Duration::default();
96 c.stage_section = StageSection::Recover
97 }
98 }
99 },
100 StageSection::Recover => {
101 if let CharacterState::RiposteMelee(c) = &mut update.character {
102 let recover_duration = if c.whiffed {
103 self.static_data.whiffed_recover_duration
104 } else {
105 self.static_data.recover_duration
106 };
107 if self.timer < recover_duration {
108 c.timer = tick_attack_or_default(
110 data,
111 self.timer,
112 Some(data.stats.recovery_speed_modifier),
113 );
114 } else {
115 end_melee_ability(data, &mut update);
117 }
118 }
119 },
120 _ => {
121 end_melee_ability(data, &mut update);
123 },
124 }
125
126 update
127 }
128}