gizmo_scripting/
api_fighter.rs1use crate::commands::{CommandQueue, ScriptCommand};
6use gizmo_core::World;
7use mlua::prelude::*;
8use std::sync::Arc;
9
10pub fn register_fighter_api(lua: &Lua, command_queue: Arc<CommandQueue>) -> Result<(), LuaError> {
11 let fighter_table = lua.create_table()?;
12
13 fighter_table.set("_buffers", lua.create_table()?)?;
15 fighter_table.set("_is_locked", lua.create_table()?)?;
16
17 {
19 let cq = command_queue.clone();
20 fighter_table.set(
21 "set_move",
22 lua.create_function(
23 move |_, (id, name, startup, active, recovery, damage): (u32, String, u32, u32, u32, f32)| {
24 cq.push(ScriptCommand::SetFighterMove {
25 id,
26 name,
27 startup,
28 active,
29 recovery,
30 damage,
31 });
32 Ok(())
33 },
34 )?,
35 )?;
36 }
37
38 {
40 let cq = command_queue.clone();
41 fighter_table.set(
42 "apply_hitstop",
43 lua.create_function(move |_, (id, frames): (u32, u32)| {
44 cq.push(ScriptCommand::ApplyHitstop(id, frames));
45 Ok(())
46 })?,
47 )?;
48 }
49
50 {
52 let cq = command_queue.clone();
53 fighter_table.set(
54 "apply_hitstun",
55 lua.create_function(move |_, (id, frames): (u32, u32)| {
56 cq.push(ScriptCommand::ApplyHitstun(id, frames));
57 Ok(())
58 })?,
59 )?;
60 }
61
62 lua.globals().set("fighter", fighter_table)?;
63
64 lua.load(
66 r#"
67 function fighter.is_locked(id)
68 return fighter._is_locked[id] or false
69 end
70
71 function fighter.check_combo(id, combo, max_gap)
72 local buffer = fighter._buffers[id]
73 if not buffer then return false end
74
75 local combo_idx = #combo
76 if combo_idx == 0 then return false end
77
78 local gap_counter = 0
79
80 for i = 1, #buffer do
81 local frame = buffer[i]
82 local target_input = combo[combo_idx]
83
84 if frame.just_pressed[target_input] then
85 combo_idx = combo_idx - 1
86 gap_counter = 0
87 if combo_idx == 0 then
88 return true
89 end
90 elseif gap_counter > max_gap then
91 return false
92 else
93 gap_counter = gap_counter + 1
94 end
95 end
96
97 return false
98 end
99 "#,
100 )
101 .exec()?;
102
103 Ok(())
104}
105
106pub fn update_fighter_read_api(lua: &Lua, world: &World) -> Result<(), LuaError> {
107 let fighter_table: LuaTable = lua.globals().get("fighter")?;
108
109 let buffers = lua.create_table()?;
110 let is_locked = lua.create_table()?;
111
112 let controllers = world.borrow::<gizmo_physics_core::components::FighterController>();
113 for (eid, _) in controllers.iter() {
114 if let Some(fighter) = controllers.get(eid) {
115 is_locked.set(eid, fighter.is_locked())?;
116
117 let frames_table = lua.create_table()?;
118 for (i, frame) in fighter.input_buffer.frames.iter().enumerate() {
119 let frame_table = lua.create_table()?;
120
121 let jp_table = lua.create_table()?;
122 for k in &frame.just_pressed {
123 jp_table.set(k.clone(), true)?;
124 }
125
126 let p_table = lua.create_table()?;
127 for k in &frame.pressed {
128 p_table.set(k.clone(), true)?;
129 }
130
131 frame_table.set("just_pressed", jp_table)?;
132 frame_table.set("pressed", p_table)?;
133
134 frames_table.set(i + 1, frame_table)?;
135 }
136 buffers.set(eid, frames_table)?;
137 }
138 }
139
140 fighter_table.set("_buffers", buffers)?;
141 fighter_table.set("_is_locked", is_locked)?;
142
143 Ok(())
144}