gizmo_physics_core/components/
fighter.rs1use serde::{Deserialize, Serialize};
2use gizmo_core::input::FighterInputBuffer;
3
4#[derive(Clone, Debug, Serialize, Deserialize)]
5pub struct FrameData {
6 pub startup: u32,
7 pub active: u32,
8 pub recovery: u32,
9 pub damage: f32,
10 pub hitstun: u32,
11 pub hitstop: u32,
12}
13
14impl Default for FrameData {
15 fn default() -> Self {
16 Self {
17 startup: 10,
18 active: 5,
19 recovery: 15,
20 damage: 10.0,
21 hitstun: 20,
22 hitstop: 5,
23 }
24 }
25}
26
27#[derive(Clone, Debug, Serialize, Deserialize, Default)]
28pub struct CombatMove {
29 pub name: String,
30 pub frame_data: FrameData,
31}
32
33#[derive(Clone, Debug, Serialize, Deserialize)]
34pub struct FighterController {
35 pub player_id: u8,
36 pub health: f32,
37 pub max_health: f32,
38 pub is_blocking: bool,
39 pub is_crouching: bool,
40
41 pub active_move: Option<CombatMove>,
43 pub current_move_frame: u32,
44
45 #[serde(skip)]
47 pub input_buffer: FighterInputBuffer,
48
49 #[serde(skip)]
51 pub hitstop_frames: u32,
52 #[serde(skip)]
53 pub hitstun_frames: u32,
54
55 pub walk_speed: f32,
56 pub dash_speed: f32,
57}
58
59impl Default for FighterController {
60 fn default() -> Self {
61 Self {
62 player_id: 1,
63 health: 100.0,
64 max_health: 100.0,
65 is_blocking: false,
66 is_crouching: false,
67 active_move: None,
68 current_move_frame: 0,
69 input_buffer: FighterInputBuffer::new(60), hitstop_frames: 0,
71 hitstun_frames: 0,
72 walk_speed: 3.0,
73 dash_speed: 10.0,
74 }
75 }
76}
77
78impl FighterController {
79 pub fn new(player_id: u8) -> Self {
80 Self {
81 player_id,
82 ..Default::default()
83 }
84 }
85
86 pub fn apply_hitstop(&mut self, frames: u32) {
88 self.hitstop_frames = frames;
89 }
90
91 pub fn apply_hitstun(&mut self, frames: u32) {
93 self.hitstun_frames = frames;
94 self.active_move = None;
95 self.current_move_frame = 0;
96 self.is_blocking = false;
97 }
98
99 pub fn is_locked(&self) -> bool {
101 self.hitstop_frames > 0 || self.hitstun_frames > 0
102 }
103
104 pub fn is_in_active_window(&self) -> bool {
106 if let Some(move_data) = &self.active_move {
107 let fd = &move_data.frame_data;
108 self.current_move_frame >= fd.startup && self.current_move_frame < (fd.startup + fd.active)
109 } else {
110 false
111 }
112 }
113}
114
115gizmo_core::impl_component!(FighterController);