launcher/pages/trainer/
ui.rs1use 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 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}