Skip to main content

gizmo_physics_core/components/
fighter.rs

1use 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    // Aktif saldırı durumu ve Frame Data takibi
42    pub active_move: Option<CombatMove>,
43    pub current_move_frame: u32,
44    
45    // Combo / Input handling
46    #[serde(skip)]
47    pub input_buffer: FighterInputBuffer,
48    
49    // Hitstop / Hitstun (Kare cinsinden bekleme süresi)
50    #[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), // 1 saniyelik buffer (60fps)
70            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    /// Karakter hasar yediğinde veya blokladığında hitstop (donma) uygula
87    pub fn apply_hitstop(&mut self, frames: u32) {
88        self.hitstop_frames = frames;
89    }
90
91    /// Sersemletme uygula
92    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    /// Karakter şu an kilitli mi (animasyon donmuş veya sersemlemiş)
100    pub fn is_locked(&self) -> bool {
101        self.hitstop_frames > 0 || self.hitstun_frames > 0
102    }
103
104    /// Aktif saldırının 'Hasar Veren' (Active) kareleri içinde miyiz?
105    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);