Skip to main content

launcher/pages/trainer/
ui.rs

1use crate::{pages::trainer::types::TrainerPageState, tasks::TaskHandle};
2use eframe::egui;
3use supreme_config::models::TrainerConfig;
4use supreme_fs::GameStorage;
5
6pub enum TrainerPageAction {
7    None,
8    InstallDependencies(TaskHandle<()>),
9    InstallHdFonts(TaskHandle<()>),
10    CheckStatus(TaskHandle<super::TrainerData>),
11}
12
13pub fn trainer_page(
14    ui: &mut egui::Ui,
15    state: &mut TrainerPageState,
16    trainer_config: &mut TrainerConfig,
17    storage: &GameStorage,
18) -> TrainerPageAction {
19    ui.horizontal(|ui| {
20        ui.heading("Dom's Trainer Settings");
21        ui.label(egui::RichText::new("ℹ").size(16.0)).on_hover_text(
22            "Note: Using the trainer injection can cause some some antivirus to see a threat.",
23        );
24    });
25    ui.add_space(10.0);
26
27    let mut action = TrainerPageAction::None;
28
29    // Trigger initial check or refresh if needed
30    if state.should_refresh() && !state.is_checking {
31        state.is_checking = true;
32        action = TrainerPageAction::CheckStatus(super::tasks::start_trainer_checks(
33            ui.ctx().clone(),
34            storage,
35        ));
36    }
37
38    if !state.dependencies_installed {
39        ui.label("⚠ These features require additional dependencies.");
40        ui.add_space(5.0);
41
42        if ui.button("🔧 Auto-install Dependencies").clicked() {
43            action = TrainerPageAction::InstallDependencies(super::tasks::start_install_deps(
44                ui.ctx().clone(),
45                storage,
46            ));
47        }
48        ui.add_space(10.0);
49    }
50
51    let ui_enabled = state.dependencies_installed;
52
53    ui.add_enabled_ui(ui_enabled, |ui| {
54        ui.checkbox(&mut trainer_config.make_ghosts_opaque, "Make Ghosts Opaque");
55        ui.checkbox(
56            &mut trainer_config.disable_direct_input,
57            "Disable DirectInput",
58        );
59
60        ui.checkbox(&mut trainer_config.hide_blinking_r, "Hide Blinking 'R'");
61        ui.checkbox(&mut trainer_config.show_replay_speed, "Show Replay Speed");
62
63        ui.add_space(10.0);
64
65        egui::CollapsingHeader::new("Advanced Settings")
66            .default_open(true)
67            .show(ui, |ui| {
68                ui.horizontal(|ui| {
69                    ui.checkbox(&mut trainer_config.use4x_fonts, "Upsized Fonts (4x)");
70                    if trainer_config.use4x_fonts
71                        && state.hd_fonts_needed
72                        && ui.button("⬇ Update to HD Fonts").clicked()
73                    {
74                        action = TrainerPageAction::InstallHdFonts(
75                            super::tasks::start_install_fonts(ui.ctx().clone(), storage),
76                        );
77                    }
78                });
79                ui.checkbox(&mut trainer_config.change_fov, "Change FOV");
80                if trainer_config.change_fov {
81                    ui.horizontal(|ui| {
82                        ui.label("FOV Aspect Ratio:");
83                        ui.add(egui::DragValue::new(&mut trainer_config.fov_width).prefix("W: "));
84                        ui.add(egui::DragValue::new(&mut trainer_config.fov_height).prefix("H: "));
85                    });
86                }
87                ui.checkbox(&mut trainer_config.enable_logging, "Enable Logging");
88                ui.checkbox(
89                    &mut trainer_config.match_ghost_sounds_to_character,
90                    "Match Ghost Sounds to Character",
91                );
92                ui.horizontal(|ui| {
93                    ui.checkbox(
94                        &mut trainer_config.enable_custom_controls,
95                        "Enable Custom Controls",
96                    );
97                    if ui.button("ℹ").on_hover_text("View controls help").clicked() {
98                        state.show_custom_controls_help = true;
99                    }
100                });
101            });
102    });
103
104    let mut show_help = state.show_custom_controls_help;
105    if show_help {
106        egui::Window::new("Supreme Snowboarding Controls")
107            .open(&mut show_help)
108            .collapsible(false)
109            .resizable(true)
110            .show(ui.ctx(), |ui| {
111                egui::ScrollArea::vertical().max_height(400.0).show(ui, |ui| {
112                    ui.heading("Default Controls");
113                    ui.add_space(8.0);
114                    egui::Grid::new("default_controls")
115                        .num_columns(2)
116                        .spacing([20.0, 8.0])
117                        .striped(true)
118                        .show(ui, |ui| {
119                            ui.label(egui::RichText::new("LEFT / RIGHT").strong());
120                            ui.label("Turn left / right.");
121                            ui.end_row();
122                            ui.label(egui::RichText::new("UP").strong());
123                            ui.label("Hold to increase speed (Tuck).");
124                            ui.end_row();
125                            ui.label(egui::RichText::new("SHIFT").strong());
126                            ui.label("Sharpens turning.");
127                            ui.end_row();
128                            ui.label(egui::RichText::new("SHIFT + ARROWS").strong());
129                            ui.label("In air: Control character's position.");
130                            ui.end_row();
131                            ui.label(egui::RichText::new("CTRL").strong());
132                            ui.label("Jump. Hold to charge, tap to hop.");
133                            ui.end_row();
134                            ui.label(egui::RichText::new("ALT").strong());
135                            ui.label("Tricks: With charged jump, arrows define grab.\nAlt toggles available grabs.");
136                            ui.end_row();
137                            ui.label(egui::RichText::new("ESC").strong());
138                            ui.label("Pause menu.");
139                            ui.end_row();
140                            ui.label(egui::RichText::new("F1 / F2").strong());
141                            ui.label("Change camera angle.");
142                            ui.end_row();
143                            ui.label(egui::RichText::new("+ / -").strong());
144                            ui.label("Adjust replay and ghost speed.");
145                            ui.end_row();
146                            ui.label(egui::RichText::new("F4").strong());
147                            ui.label("Take screenshot (saved in Supreme/images/).");
148                            ui.end_row();
149                            ui.label(egui::RichText::new("F5").strong());
150                            ui.label("Restart race.");
151                            ui.end_row();
152                        });
153
154                    ui.add_space(16.0);
155
156                    ui.heading("Custom Controls");
157                    ui.add_space(8.0);
158                    egui::Grid::new("custom_controls")
159                        .num_columns(2)
160                        .spacing([20.0, 8.0])
161                        .striped(true)
162                        .show(ui, |ui| {
163                            ui.label(egui::RichText::new("M").strong());
164                            ui.label("Toggle music.");
165                            ui.end_row();
166                            ui.label(egui::RichText::new("SHIFT + M").strong());
167                            ui.label("Toggle sounds.");
168                            ui.end_row();
169                            ui.label(egui::RichText::new("F7").strong());
170                            ui.label("Go to replay camera in player POV.");
171                            ui.end_row();
172                            ui.label(egui::RichText::new("G").strong());
173                            ui.label("Toggle ghost transparency (requires race restart).");
174                            ui.end_row();
175                        });
176                });
177            });
178        state.show_custom_controls_help = show_help;
179    }
180
181    action
182}