gizmo_scripting/
api_scene.rs1use crate::commands::{CommandQueue, ScriptCommand};
6use gizmo_core::World;
7use mlua::prelude::*;
8use std::sync::Arc;
9
10pub fn register_scene_api(lua: &Lua, command_queue: Arc<CommandQueue>) -> Result<(), LuaError> {
12 let scene_table = lua.create_table()?;
13
14 {
16 let cq = command_queue.clone();
17 scene_table.set(
18 "save",
19 lua.create_function(move |_, path: String| {
20 cq.push(ScriptCommand::SaveScene(path));
21 Ok(())
22 })?,
23 )?;
24 }
25 {
26 let cq = command_queue.clone();
27 scene_table.set(
28 "load",
29 lua.create_function(move |_, path: String| {
30 cq.push(ScriptCommand::LoadScene(path));
31 Ok(())
32 })?,
33 )?;
34 }
35
36 lua.globals().set("scene", scene_table)?;
37
38 let dialogue_table = lua.create_table()?;
40 {
41 let cq = command_queue.clone();
42 dialogue_table.set(
43 "show",
44 lua.create_function(
45 move |_, (speaker, text, duration): (String, String, Option<f32>)| {
46 cq.push(ScriptCommand::ShowDialogue {
47 speaker,
48 text,
49 duration: duration.unwrap_or(3.0),
50 });
51 Ok(())
52 },
53 )?,
54 )?;
55 }
56 {
57 let cq = command_queue.clone();
58 dialogue_table.set(
59 "hide",
60 lua.create_function(move |_, ()| {
61 cq.push(ScriptCommand::HideDialogue);
62 Ok(())
63 })?,
64 )?;
65 }
66 lua.globals().set("dialogue", dialogue_table)?;
67
68 let cutscene_table = lua.create_table()?;
70 {
71 let cq = command_queue.clone();
72 cutscene_table.set(
73 "play",
74 lua.create_function(move |_, name: String| {
75 cq.push(ScriptCommand::TriggerCutscene(name));
76 Ok(())
77 })?,
78 )?;
79 }
80 {
81 let cq = command_queue.clone();
82 cutscene_table.set(
83 "stop",
84 lua.create_function(move |_, ()| {
85 cq.push(ScriptCommand::EndCutscene);
86 Ok(())
87 })?,
88 )?;
89 }
90 lua.globals().set("cutscene", cutscene_table)?;
91
92 let race_table = lua.create_table()?;
94 {
95 let cq = command_queue.clone();
96 race_table.set(
97 "add_checkpoint",
98 lua.create_function(
99 move |_, (id, x, y, z, radius): (u32, f32, f32, f32, Option<f32>)| {
100 cq.push(ScriptCommand::AddCheckpoint {
101 id,
102 position: gizmo_math::Vec3::new(x, y, z),
103 radius: radius.unwrap_or(5.0),
104 });
105 Ok(())
106 },
107 )?,
108 )?;
109 }
110 {
111 let cq = command_queue.clone();
112 race_table.set(
113 "activate_checkpoint",
114 lua.create_function(move |_, id: u32| {
115 cq.push(ScriptCommand::ActivateCheckpoint(id));
116 Ok(())
117 })?,
118 )?;
119 }
120 {
121 let cq = command_queue.clone();
122 race_table.set(
123 "finish",
124 lua.create_function(move |_, winner: String| {
125 cq.push(ScriptCommand::FinishRace {
126 winner_name: winner,
127 });
128 Ok(())
129 })?,
130 )?;
131 }
132 {
133 let cq = command_queue.clone();
134 race_table.set(
135 "reset",
136 lua.create_function(move |_, ()| {
137 cq.push(ScriptCommand::ResetRace);
138 Ok(())
139 })?,
140 )?;
141 }
142 {
143 let cq = command_queue.clone();
144 race_table.set(
145 "start",
146 lua.create_function(move |_, ()| {
147 cq.push(ScriptCommand::StartRace);
148 Ok(())
149 })?,
150 )?;
151 }
152 lua.globals().set("race", race_table)?;
153
154 let camera_table = lua.create_table()?;
156 {
157 let cq = command_queue.clone();
158 camera_table.set(
159 "follow",
160 lua.create_function(move |_, entity_id: u32| {
161 cq.push(ScriptCommand::SetCameraTarget(entity_id));
162 Ok(())
163 })?,
164 )?;
165 }
166 {
167 let cq = command_queue.clone();
168 camera_table.set(
169 "set_fov",
170 lua.create_function(move |_, fov: f32| {
171 cq.push(ScriptCommand::SetCameraFov(fov));
172 Ok(())
173 })?,
174 )?;
175 }
176 lua.globals().set("camera", camera_table)?;
177
178 Ok(())
179}
180
181pub fn update_scene_api(lua: &Lua, world: &World) -> Result<(), LuaError> {
183 let scene_table: LuaTable = lua.globals().get("scene")?;
184
185 let entities_table = lua.create_table()?;
187 let mut idx = 1;
188 for entity in world.iter_alive_entities() {
189 entities_table.set(idx, entity.id())?;
190 idx += 1;
191 }
192 scene_table.set("_entities", entities_table)?;
193
194 let name_map = lua.create_table()?;
196 let names = world.borrow::<gizmo_core::EntityName>();
197 for (eid, _) in names.iter() {
198 if let Some(n) = names.get(eid) {
199 name_map.set(n.0.clone(), eid)?;
200 }
201 }
202 scene_table.set("_name_map", name_map)?;
203
204 lua.load(
206 r#"
207 function scene.get_all_entities()
208 return scene._entities or {}
209 end
210
211 function scene.find_by_name(name)
212 return scene._name_map[name]
213 end
214
215 function scene.entity_count()
216 local count = 0
217 for _ in pairs(scene._entities or {}) do count = count + 1 end
218 return count
219 end
220 "#,
221 )
222 .exec()?;
223
224 Ok(())
225}