kvas_engine/
script_game.rs1use crate::canvas::Canvas;
26use crate::components::{Camera, Transform};
27use crate::script::Ctx;
28use crate::storage::{SaveInfo, Storage};
29use kvas_ecs::Entity;
30
31impl Ctx<'_> {
32 pub fn ui(&self) -> &Canvas {
34 &self.input.canvas
35 }
36 pub fn ui_width(&self) -> f32 {
38 self.input.canvas.width()
39 }
40
41 pub fn storage(&self) -> Storage {
44 self.input.storage()
45 }
46 pub fn save_game(&self, slot: &str, title: &str, data: &serde_json::Value) -> Result<(), String> {
48 self.input.storage().save(slot, title, data)
49 }
50 pub fn load_game(&self, slot: &str) -> Option<serde_json::Value> {
52 self.input.storage().load(slot)
53 }
54 pub fn save_slots(&self) -> Vec<SaveInfo> {
56 self.input.storage().slots()
57 }
58 pub fn has_save(&self, slot: &str) -> bool {
60 self.input.storage().has_save(slot)
61 }
62 pub fn setting_f32(&self, key: &str, default: f32) -> f32 {
64 self.input.storage().setting(key).and_then(|v| v.as_f64()).map_or(default, |v| v as f32)
65 }
66 pub fn setting_bool(&self, key: &str, default: bool) -> bool {
68 self.input.storage().setting(key).and_then(|v| v.as_bool()).unwrap_or(default)
69 }
70 pub fn setting_text(&self, key: &str, default: &str) -> String {
72 self.input.storage().setting(key).and_then(|v| v.as_str().map(str::to_string)).unwrap_or_else(|| default.to_string())
73 }
74 pub fn set_setting(&self, key: &str, value: serde_json::Value) {
76 if let Err(e) = self.input.storage().set_setting(key, value) {
77 eprintln!("setting {key}: {e}");
78 }
79 }
80
81 pub fn active_camera(&self) -> Option<Entity> {
84 crate::components::active_camera(&self.scene.world)
85 }
86 pub fn set_active_camera(&mut self, camera: Entity) -> bool {
88 crate::components::set_active_camera(&mut self.scene.world, camera)
89 }
90 pub fn set_active_camera_named(&mut self, name: &str) -> bool {
92 match self.find(name) {
93 Some(e) => self.set_active_camera(e),
94 None => false,
95 }
96 }
97 pub fn add_camera_effect(&mut self, camera: Entity, shader: &str, params: [f32; 4]) -> Option<usize> {
99 let c = self.scene.world.get_mut::<Camera>(camera)?;
100 c.effects.push(crate::fx::PostEffect { shader: shader.to_string(), enabled: true, params });
101 Some(c.effects.len() - 1)
102 }
103 pub fn set_camera_effect(&mut self, camera: Entity, index: usize, enabled: bool, params: [f32; 4]) {
105 if let Some(fx) = self.scene.world.get_mut::<Camera>(camera).and_then(|c| c.effects.get_mut(index)) {
106 fx.enabled = enabled;
107 fx.params = params;
108 }
109 }
110 pub fn set_camera_fov(&mut self, camera: Entity, fov: f32) {
112 if let Some(c) = self.scene.world.get_mut::<Camera>(camera) {
113 c.fov = fov.clamp(5.0, 170.0);
114 c.focal_length = 0.0;
115 }
116 }
117 pub fn camera_position(&self) -> Option<glam::Vec3> {
119 let e = self.active_camera()?;
120 Some(crate::hierarchy::global_matrix(&self.scene.world, e).w_axis.truncate())
121 }
122 pub fn camera_forward(&self) -> Option<glam::Vec3> {
124 let e = self.active_camera()?;
125 Some(-crate::hierarchy::global_matrix(&self.scene.world, e).z_axis.truncate().normalize_or_zero())
126 }
127 pub fn place_camera(&mut self, camera: Entity, position: glam::Vec3, target: glam::Vec3) {
129 if let Some(t) = self.scene.world.get_mut::<Transform>(camera) {
130 t.position = position;
131 t.look_at(target, glam::Vec3::Y);
132 }
133 }
134
135 pub fn set_reverb(&mut self, amount: f32, room_ms: f32) {
139 self.scene.audio.reverb = amount.clamp(0.0, 1.0);
140 self.scene.audio.reverb_room_ms = room_ms.clamp(5.0, 400.0);
141 }
142 pub fn set_volumes(&mut self, master: f32, music: f32, effects: f32) {
144 self.scene.audio.master_volume = master.clamp(0.0, 2.0);
145 self.scene.audio.music_volume = music.clamp(0.0, 2.0);
146 self.scene.audio.effects_volume = effects.clamp(0.0, 2.0);
147 }
148
149 pub fn quit_game(&self) {
152 self.input.request_quit();
153 }
154 pub fn set_fullscreen(&self, on: bool) {
156 self.input.request_fullscreen(on);
157 }
158}