Skip to main content

gizmo_scripting/
api_scene.rs

1//! Scene API — Lua'ya sunulan sahne ve oyun yönetim fonksiyonları
2//!
3//! Kapsam: sahne kaydet/yükle, diyalog, ara sahne, yarış sistemi, kamera.
4
5use crate::commands::{CommandQueue, ScriptCommand};
6use gizmo_core::World;
7use mlua::prelude::*;
8use std::sync::Arc;
9
10/// Scene + Game API fonksiyonlarını Lua'ya kaydeder
11pub fn register_scene_api(lua: &Lua, command_queue: Arc<CommandQueue>) -> Result<(), LuaError> {
12    let scene_table = lua.create_table()?;
13
14    // --- SAHNE KAYDET / YÜKLE ---
15    {
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    // --- DİYALOG ---
39    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    // --- ARA SAHNE (CUTSCENE) ---
69    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    // --- YARIŞ SİSTEMİ ---
93    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    // --- KAMERA ---
155    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
181/// Her frame sahne verisini Lua'ya günceller (entity listesi, isim arama)
182pub fn update_scene_api(lua: &Lua, world: &World) -> Result<(), LuaError> {
183    let scene_table: LuaTable = lua.globals().get("scene")?;
184
185    // Entity listesini güncelle
186    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    // İsim → ID eşleme tablosu
195    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 helper'ları (sadece bir kere yüklenmeli ama idempotent)
205    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}