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)]
5#[non_exhaustive]
6pub struct FrameData {
7    pub startup: u32,
8    pub active: u32,
9    pub recovery: u32,
10    pub damage: f32,
11    pub hitstun: u32,
12    pub hitstop: u32,
13}
14
15impl Default for FrameData {
16    fn default() -> Self {
17        Self {
18            startup: 10,
19            active: 5,
20            recovery: 15,
21            damage: 10.0,
22            hitstun: 20,
23            hitstop: 5,
24        }
25    }
26}
27
28#[derive(Clone, Debug, Serialize, Deserialize, Default)]
29#[non_exhaustive]
30pub struct CombatMove {
31    pub name: String,
32    pub frame_data: FrameData,
33}
34
35#[derive(Clone, Debug, Serialize, Deserialize)]
36#[non_exhaustive]
37pub struct FighterController {
38    pub player_id: u8,
39    pub health: f32,
40    pub max_health: f32,
41    pub is_blocking: bool,
42    pub is_crouching: bool,
43    
44    // Aktif saldırı durumu ve Frame Data takibi
45    pub active_move: Option<CombatMove>,
46    pub current_move_frame: u32,
47    
48    // Combo / Input handling
49    #[serde(skip)]
50    pub input_buffer: FighterInputBuffer,
51    
52    // Hitstop / Hitstun (Kare cinsinden bekleme süresi)
53    #[serde(skip)]
54    pub hitstop_frames: u32,
55    #[serde(skip)]
56    pub hitstun_frames: u32,
57
58    pub walk_speed: f32,
59    pub dash_speed: f32,
60}
61
62impl Default for FighterController {
63    fn default() -> Self {
64        Self {
65            player_id: 1,
66            health: 100.0,
67            max_health: 100.0,
68            is_blocking: false,
69            is_crouching: false,
70            active_move: None,
71            current_move_frame: 0,
72            input_buffer: FighterInputBuffer::new(60), // 1 saniyelik buffer (60fps)
73            hitstop_frames: 0,
74            hitstun_frames: 0,
75            walk_speed: 3.0,
76            dash_speed: 10.0,
77        }
78    }
79}
80
81impl FighterController {
82    pub fn new(player_id: u8) -> Self {
83        Self {
84            player_id,
85            ..Default::default()
86        }
87    }
88    
89    /// Karakter hasar yediğinde veya blokladığında hitstop (donma) uygula
90    pub fn apply_hitstop(&mut self, frames: u32) {
91        self.hitstop_frames = frames;
92    }
93
94    /// Sersemletme uygula
95    pub fn apply_hitstun(&mut self, frames: u32) {
96        self.hitstun_frames = frames;
97        self.active_move = None;
98        self.current_move_frame = 0;
99        self.is_blocking = false;
100    }
101
102    /// Karakter şu an kilitli mi (animasyon donmuş veya sersemlemiş)
103    pub fn is_locked(&self) -> bool {
104        self.hitstop_frames > 0 || self.hitstun_frames > 0
105    }
106
107    /// Aktif saldırının 'Hasar Veren' (Active) kareleri içinde miyiz?
108    pub fn is_in_active_window(&self) -> bool {
109        if let Some(move_data) = &self.active_move {
110            let fd = &move_data.frame_data;
111            self.current_move_frame >= fd.startup && self.current_move_frame < (fd.startup + fd.active)
112        } else {
113            false
114        }
115    }
116}
117
118gizmo_core::impl_component!(FighterController);