1use super::SessionState;
2use crate::{
3 GlobalState,
4 audio::SfxChannelSettings,
5 controller::ControllerSettings,
6 game_input::GameInput,
7 hud::{
8 AutoPressBehavior, BarNumbers, BuffPosition, ChatTab, CrosshairType, Intro, PressBehavior,
9 ScaleChange, ShortcutNumbers, XpBar,
10 },
11 render::RenderMode,
12 settings::{
13 AudioSettings, ChatSettings, ControlSettings, Fps, GamepadSettings, GameplaySettings,
14 GraphicsSettings, InterfaceSettings, audio::AudioVolume,
15 },
16 window::{FullScreenSettings, Window},
17};
18use common::comp::inventory::InventorySortOrder;
19use i18n::{LanguageMetadata, LocalizationHandle};
20use std::rc::Rc;
21
22#[derive(Clone)]
23pub enum Audio {
24 AdjustMasterVolume(f32),
25 MuteMasterVolume(bool),
26 AdjustInactiveMasterVolume(f32),
27 MuteInactiveMasterVolume(bool),
28 AdjustMusicVolume(f32),
29 MuteMusicVolume(bool),
30 AdjustSfxVolume(f32),
31 MuteSfxVolume(bool),
32 AdjustAmbienceVolume(f32),
33 MuteAmbienceVolume(bool),
34 RainAmbience(bool),
35 AdjustMusicSpacing(f32),
36 ToggleCombatMusic(bool),
37 SetNumSfxChannels(SfxChannelSettings),
38 ResetAudioSettings,
39}
40#[derive(Clone)]
41pub enum Chat {
42 Transp(f32),
43 CharName(bool),
44 ChangeChatTab(Option<usize>),
45 ChatTabUpdate(usize, ChatTab),
46 ChatTabInsert(usize, ChatTab),
47 ChatTabMove(usize, usize), ChatTabRemove(usize),
49 ResetChatSettings,
50}
51#[derive(Clone)]
52pub enum Control {
53 ChangeBinding(GameInput),
54 RemoveBinding(GameInput),
55 ResetKeyBindings,
56}
57#[derive(Clone)]
58pub enum Gamepad {}
59#[derive(Clone)]
60pub enum Gameplay {
61 AdjustMousePan(u32),
62 AdjustMouseZoom(u32),
63 AdjustCameraClamp(u32),
64 AdjustWalkingSpeed(f32),
65
66 ToggleControllerYInvert(bool),
67 ToggleMouseYInvert(bool),
68 ToggleZoomInvert(bool),
69 ToggleSmoothPan(bool),
70
71 ChangeFreeLookBehavior(PressBehavior),
72 ChangeAutoWalkBehavior(PressBehavior),
73 ChangeWalkingSpeedBehavior(PressBehavior),
74 ChangeCameraClampBehavior(PressBehavior),
75 ChangeZoomLockBehavior(AutoPressBehavior),
76 ChangeStopAutoWalkOnInput(bool),
77 ChangeAutoCamera(bool),
78 ChangeBowZoom(bool),
79 ChangeZoomLock(bool),
80 ChangeShowAllRecipes(bool),
81
82 AdjustAimOffsetX(f32),
83 AdjustAimOffsetY(f32),
84
85 ResetGameplaySettings,
86}
87#[derive(Clone)]
88pub enum Graphics {
89 AdjustTerrainViewDistance(u32),
90 AdjustEntityViewDistance(u32),
91 AdjustLodDistance(u32),
92 AdjustLodDetail(u32),
93 AdjustSpriteRenderDistance(u32),
94 AdjustFigureLoDRenderDistance(u32),
95
96 ChangeMaxFPS(Fps),
97 ChangeMaxBackgroundFPS(Fps),
98 ChangeFOV(u16),
99
100 ChangeGamma(f32),
101 ChangeExposure(f32),
102 ChangeAmbiance(f32),
103
104 ChangeRenderMode(Box<RenderMode>),
105
106 ChangeFullscreenMode(FullScreenSettings),
107 ToggleParticlesEnabled(bool),
108 ToggleWeaponTrailsEnabled(bool),
109
110 ResetGraphicsSettings,
111 ChangeGraphicsSettings(Rc<dyn Fn(GraphicsSettings) -> GraphicsSettings>),
112}
113#[derive(Clone)]
114pub enum Interface {
115 Sct(bool),
116 SctRoundDamage(bool),
117 SctDamageAccumDuration(f32),
118 SctIncomingDamage(bool),
119 SctIncomingDamageAccumDuration(f32),
120 SpeechBubbleSelf(bool),
121 SpeechBubbleDarkMode(bool),
122 SpeechBubbleIcon(bool),
123 ToggleDebug(bool),
124 ToggleHitboxes(bool),
125 ToggleChat(bool),
126 ToggleTips(bool),
127 ToggleHotkeyHints(bool),
128
129 CrosshairTransp(f32),
130 CrosshairType(CrosshairType),
131 Intro(Intro),
132 ToggleXpBar(XpBar),
133 ToggleHealthPrefixes(bool),
134 ToggleBarNumbers(BarNumbers),
135 ToggleAlwaysShowBars(bool),
136 TogglePoiseBar(bool),
137 ToggleShortcutNumbers(ShortcutNumbers),
138 BuffPosition(BuffPosition),
139 RowBackgroundOpacity(f32),
140
141 UiScale(ScaleChange),
142 MinimapShow(bool),
144 MinimapFaceNorth(bool),
145 MinimapZoom(f64),
146 MinimapScale(f64),
147 MinimapColoredPlayerMarker(bool),
148 MapZoom(f64),
150 MapShowTopoMap(bool),
151 MapShowDifficulty(bool),
152 MapShowTowns(bool),
153 MapShowDungeons(bool),
154 MapShowCastles(bool),
155 MapShowBridges(bool),
156 MapShowGliderCourses(bool),
157 MapShowCaves(bool),
158 MapShowTrees(bool),
159 MapShowPeaks(bool),
160 MapShowBiomes(bool),
161 MapShowVoxelMap(bool),
162 MapShowQuests(bool),
163 AccumExperience(bool),
164 SlotsUsePrefixes(bool),
166 SlotsPrefixSwitchPoint(u32),
167
168 ResetInterfaceSettings,
169}
170#[derive(Clone)]
171pub enum Inventory {
172 ChangeSortOrder(InventorySortOrder),
173}
174#[derive(Clone)]
175pub enum Language {
176 ChangeLanguage(Box<LanguageMetadata>),
177 ToggleSendToServer(bool),
178 ToggleEnglishFallback(bool),
179}
180#[derive(Clone)]
181pub enum Networking {
182 AdjustTerrainViewDistance(u32),
183 AdjustEntityViewDistance(u32),
184 ChangePlayerPhysicsBehavior {
185 server_authoritative: bool,
186 },
187 ToggleLossyTerrainCompression(bool),
188
189 #[cfg(feature = "discord")]
190 ToggleDiscordIntegration(bool),
191 }
194
195#[derive(Clone)]
196pub enum Accessibility {
197 ChangeRenderMode(Box<RenderMode>),
198 SetSubtitles(bool),
199}
200
201#[derive(Clone)]
202pub enum SettingsChange {
203 Audio(Audio),
204 Chat(Chat),
205 Control(Control),
206 Gamepad(Gamepad),
207 Gameplay(Gameplay),
208 Graphics(Graphics),
209 Interface(Interface),
210 Inventory(Inventory),
211 Language(Language),
212 Networking(Networking),
213 Accessibility(Accessibility),
214}
215
216macro_rules! settings_change_from {
217 ($i: ident) => {
218 impl From<$i> for SettingsChange {
219 fn from(change: $i) -> Self { SettingsChange::$i(change) }
220 }
221 };
222}
223settings_change_from!(Audio);
224settings_change_from!(Chat);
225settings_change_from!(Control);
226settings_change_from!(Gamepad);
227settings_change_from!(Gameplay);
228settings_change_from!(Graphics);
229settings_change_from!(Interface);
230settings_change_from!(Language);
231settings_change_from!(Networking);
232settings_change_from!(Accessibility);
233
234impl SettingsChange {
235 pub fn process(self, global_state: &mut GlobalState, session_state: &mut SessionState) {
236 let settings = &mut global_state.settings;
237
238 match self {
239 SettingsChange::Audio(audio_change) => {
240 fn update_volume(audio: &mut AudioVolume, volume: f32) -> f32 {
241 audio.volume = volume;
242 audio.get_checked()
243 }
244 fn update_muted(audio: &mut AudioVolume, muted: bool) -> f32 {
245 audio.muted = muted;
246 audio.get_checked()
247 }
248
249 match audio_change {
250 Audio::AdjustMasterVolume(master_volume) => {
251 let volume_checked =
252 update_volume(&mut settings.audio.master_volume, master_volume);
253
254 global_state.audio.set_master_volume(volume_checked);
255 },
256 Audio::MuteMasterVolume(master_muted) => {
257 let volume_checked =
258 update_muted(&mut settings.audio.master_volume, master_muted);
259
260 global_state.audio.set_master_volume(volume_checked);
261 },
262 Audio::AdjustInactiveMasterVolume(inactive_master_volume_perc) => {
263 settings.audio.inactive_master_volume_perc.volume =
264 inactive_master_volume_perc;
265 },
266 Audio::MuteInactiveMasterVolume(inactive_master_volume_muted) => {
267 settings.audio.inactive_master_volume_perc.muted =
268 inactive_master_volume_muted;
269 },
270 Audio::AdjustMusicVolume(music_volume) => {
271 let volume_checked =
272 update_volume(&mut settings.audio.music_volume, music_volume);
273
274 global_state.audio.set_music_volume(volume_checked);
275 },
276 Audio::MuteMusicVolume(music_muted) => {
277 let volume_checked =
278 update_muted(&mut settings.audio.music_volume, music_muted);
279
280 global_state.audio.set_music_volume(volume_checked);
281 },
282 Audio::AdjustSfxVolume(sfx_volume) => {
283 let volume_checked =
284 update_volume(&mut settings.audio.sfx_volume, sfx_volume);
285
286 global_state.audio.set_sfx_volume(volume_checked);
287 },
288 Audio::MuteSfxVolume(sfx_muted) => {
289 let volume_checked =
290 update_muted(&mut settings.audio.sfx_volume, sfx_muted);
291
292 global_state.audio.set_sfx_volume(volume_checked);
293 },
294 Audio::AdjustAmbienceVolume(ambience_volume) => {
295 global_state.audio.set_ambience_volume(ambience_volume);
296
297 settings.audio.ambience_volume.volume = ambience_volume;
298 },
299 Audio::MuteAmbienceVolume(ambience_muted) => {
300 let volume_checked =
301 update_muted(&mut settings.audio.ambience_volume, ambience_muted);
302
303 global_state.audio.set_ambience_volume(volume_checked);
304 },
305 Audio::RainAmbience(rain_ambience_enabled) => {
306 settings.audio.rain_ambience_enabled = rain_ambience_enabled;
307 },
308 Audio::AdjustMusicSpacing(multiplier) => {
309 global_state.audio.set_music_spacing(multiplier);
310
311 settings.audio.music_spacing = multiplier;
312 },
313 Audio::ToggleCombatMusic(combat_music_enabled) => {
314 global_state.audio.combat_music_enabled = combat_music_enabled
315 },
316 Audio::SetNumSfxChannels(level) => {
317 let num = SfxChannelSettings::to_usize(&level);
318 global_state.audio.set_num_sfx_channels(num);
319 settings.audio.num_sfx_channels = num;
320 },
321 Audio::ResetAudioSettings => {
322 let previous_sample_rate = settings.audio.sample_rate;
323 let previous_buffer_size = settings.audio.buffer_size;
324 settings.audio = AudioSettings::default();
325 settings.audio.sample_rate = previous_sample_rate;
326 settings.audio.buffer_size = previous_buffer_size;
327
328 let audio = &mut global_state.audio;
329
330 audio.set_master_volume(settings.audio.master_volume.get_checked());
331 audio.set_music_volume(settings.audio.music_volume.get_checked());
332 audio.set_ambience_volume(settings.audio.ambience_volume.get_checked());
333 audio.set_sfx_volume(settings.audio.sfx_volume.get_checked());
334 audio.set_music_spacing(settings.audio.music_spacing);
335 },
336 }
337 },
338 SettingsChange::Chat(chat_change) => {
339 let chat_tabs = &mut settings.chat.chat_tabs;
340 match chat_change {
341 Chat::Transp(chat_opacity) => {
342 settings.chat.chat_opacity = chat_opacity;
343 },
344 Chat::CharName(chat_char_name) => {
345 settings.chat.chat_character_name = chat_char_name;
346 },
347 Chat::ChangeChatTab(chat_tab_index) => {
348 settings.chat.chat_tab_index =
349 chat_tab_index.filter(|i| *i < chat_tabs.len());
350 },
351 Chat::ChatTabUpdate(i, chat_tab) => {
352 if i < chat_tabs.len() {
353 chat_tabs[i] = chat_tab;
354 }
355 },
356 Chat::ChatTabInsert(i, chat_tab) => {
357 if i <= chat_tabs.len() {
358 settings.chat.chat_tabs.insert(i, chat_tab);
359 }
360 },
361 Chat::ChatTabMove(i, j) => {
362 if i < chat_tabs.len() && j < chat_tabs.len() {
363 let chat_tab = settings.chat.chat_tabs.remove(i);
364 settings.chat.chat_tabs.insert(j, chat_tab);
365 }
366 },
367 Chat::ChatTabRemove(i) => {
368 if i < chat_tabs.len() {
369 settings.chat.chat_tabs.remove(i);
370 }
371 },
372 Chat::ResetChatSettings => {
373 settings.chat = ChatSettings::default();
374 },
375 }
376 },
377 SettingsChange::Control(control_change) => match control_change {
378 Control::ChangeBinding(game_input) => {
379 global_state.window.set_keybinding_mode(game_input);
380 },
381 Control::RemoveBinding(game_input) => {
382 settings.controls.remove_binding(game_input);
383 },
384 Control::ResetKeyBindings => {
385 settings.controls = ControlSettings::default();
386 },
387 },
388 SettingsChange::Gamepad(gamepad_change) => match gamepad_change {},
389 SettingsChange::Gameplay(gameplay_change) => {
390 let window = &mut global_state.window;
391 match gameplay_change {
392 Gameplay::AdjustMousePan(sensitivity) => {
393 window.pan_sensitivity = sensitivity;
394 settings.gameplay.pan_sensitivity = sensitivity;
395 },
396 Gameplay::AdjustMouseZoom(sensitivity) => {
397 window.zoom_sensitivity = sensitivity;
398 settings.gameplay.zoom_sensitivity = sensitivity;
399 },
400 Gameplay::AdjustCameraClamp(angle) => {
401 settings.gameplay.camera_clamp_angle = angle;
402 },
403 Gameplay::AdjustWalkingSpeed(speed) => {
404 settings.gameplay.walking_speed = speed;
405 },
406 Gameplay::ToggleControllerYInvert(controller_y_inverted) => {
407 window.controller_settings.pan_invert_y = controller_y_inverted;
408 settings.controller.pan_invert_y = controller_y_inverted;
409 },
410 Gameplay::ToggleMouseYInvert(mouse_y_inverted) => {
411 window.mouse_y_inversion = mouse_y_inverted;
412 settings.gameplay.mouse_y_inversion = mouse_y_inverted;
413 },
414 Gameplay::ToggleZoomInvert(zoom_inverted) => {
415 window.zoom_inversion = zoom_inverted;
416 settings.gameplay.zoom_inversion = zoom_inverted;
417 },
418 Gameplay::ToggleSmoothPan(smooth_pan_enabled) => {
419 settings.gameplay.smooth_pan_enable = smooth_pan_enabled;
420 },
421 Gameplay::ChangeFreeLookBehavior(behavior) => {
422 settings.gameplay.free_look_behavior = behavior;
423 },
424 Gameplay::ChangeAutoWalkBehavior(behavior) => {
425 settings.gameplay.auto_walk_behavior = behavior;
426 },
427 Gameplay::ChangeWalkingSpeedBehavior(behavior) => {
428 settings.gameplay.walking_speed_behavior = behavior;
429 },
430 Gameplay::ChangeCameraClampBehavior(behavior) => {
431 settings.gameplay.camera_clamp_behavior = behavior;
432 },
433 Gameplay::ChangeZoomLockBehavior(state) => {
434 settings.gameplay.zoom_lock_behavior = state;
435 },
436 Gameplay::ChangeStopAutoWalkOnInput(state) => {
437 settings.gameplay.stop_auto_walk_on_input = state;
438 },
439 Gameplay::ChangeAutoCamera(state) => {
440 settings.gameplay.auto_camera = state;
441 },
442 Gameplay::ChangeBowZoom(state) => {
443 settings.gameplay.bow_zoom = state;
444 },
445 Gameplay::ChangeZoomLock(state) => {
446 settings.gameplay.zoom_lock = state;
447 },
448 Gameplay::AdjustAimOffsetX(offset) => {
449 settings.gameplay.aim_offset_x = offset;
450 },
451 Gameplay::AdjustAimOffsetY(offset) => {
452 settings.gameplay.aim_offset_y = offset;
453 },
454 Gameplay::ResetGameplaySettings => {
455 settings.gameplay = GameplaySettings::default();
457 settings.controller = GamepadSettings::default();
459 window.controller_settings = ControllerSettings::from(&settings.controller);
460 window.pan_sensitivity = settings.gameplay.pan_sensitivity;
462 window.zoom_sensitivity = settings.gameplay.zoom_sensitivity;
464 window.zoom_inversion = settings.gameplay.zoom_inversion;
466 window.mouse_y_inversion = settings.gameplay.mouse_y_inversion;
468 },
469 Gameplay::ChangeShowAllRecipes(state) => {
470 settings.gameplay.show_all_recipes = state;
471 },
472 }
473 },
474 SettingsChange::Graphics(graphics_change) => {
475 let mut change_preset = false;
476
477 match graphics_change {
478 Graphics::AdjustTerrainViewDistance(terrain_vd) => {
479 adjust_terrain_view_distance(terrain_vd, settings, session_state)
480 },
481 Graphics::AdjustEntityViewDistance(entity_vd) => {
482 adjust_entity_view_distance(entity_vd, settings, session_state)
483 },
484 Graphics::AdjustLodDistance(lod_distance) => {
485 session_state
486 .client
487 .borrow_mut()
488 .set_lod_distance(lod_distance);
489
490 settings.graphics.lod_distance = lod_distance;
491 },
492 Graphics::AdjustLodDetail(lod_detail) => {
493 session_state.scene.lod.set_detail(lod_detail);
494
495 settings.graphics.lod_detail = lod_detail;
496 },
497 Graphics::AdjustSpriteRenderDistance(sprite_render_distance) => {
498 settings.graphics.sprite_render_distance = sprite_render_distance;
499 },
500 Graphics::AdjustFigureLoDRenderDistance(figure_lod_render_distance) => {
501 settings.graphics.figure_lod_render_distance = figure_lod_render_distance;
502 },
503 Graphics::ChangeMaxFPS(fps) => {
504 settings.graphics.max_fps = fps;
505 },
506 Graphics::ChangeMaxBackgroundFPS(fps) => {
507 settings.graphics.max_background_fps = fps;
508 },
509 Graphics::ChangeFOV(new_fov) => {
510 settings.graphics.fov = new_fov;
511 session_state.scene.camera_mut().set_fov_deg(new_fov);
512 session_state
513 .scene
514 .camera_mut()
515 .compute_dependents(&session_state.client.borrow().state().terrain());
516 },
517 Graphics::ChangeGamma(new_gamma) => {
518 settings.graphics.gamma = new_gamma;
519 },
520 Graphics::ChangeExposure(new_exposure) => {
521 settings.graphics.exposure = new_exposure;
522 },
523 Graphics::ChangeAmbiance(new_ambiance) => {
524 settings.graphics.ambiance = new_ambiance;
525 },
526 Graphics::ChangeRenderMode(new_render_mode) => {
527 change_render_mode(*new_render_mode, &mut global_state.window, settings);
528 },
529 Graphics::ChangeFullscreenMode(new_fullscreen_settings) => {
530 global_state
531 .window
532 .set_fullscreen_mode(new_fullscreen_settings);
533 settings.graphics.fullscreen = new_fullscreen_settings;
534 },
535 Graphics::ToggleParticlesEnabled(particles_enabled) => {
536 settings.graphics.particles_enabled = particles_enabled;
537 },
538 Graphics::ToggleWeaponTrailsEnabled(weapon_trails_enabled) => {
539 settings.graphics.weapon_trails_enabled = weapon_trails_enabled;
540 },
541 Graphics::ResetGraphicsSettings => {
542 settings.graphics = GraphicsSettings::default();
543 change_preset = true;
544 global_state
546 .window
547 .set_fullscreen_mode(settings.graphics.fullscreen);
548 global_state
550 .window
551 .set_size(settings.graphics.window.size.into());
552 },
553 Graphics::ChangeGraphicsSettings(f) => {
554 settings.graphics = f(settings.graphics.clone());
555 change_preset = true;
556 },
557 }
558
559 if change_preset {
560 let graphics = &settings.graphics;
561 client_set_view_distance(settings, session_state);
563 session_state.scene.camera_mut().set_fov_deg(graphics.fov);
565 session_state
566 .scene
567 .camera_mut()
568 .compute_dependents(&session_state.client.borrow().state().terrain());
569 session_state.scene.lod.set_detail(graphics.lod_detail);
571 session_state
573 .client
574 .borrow_mut()
575 .set_lod_distance(graphics.lod_distance);
576 global_state
578 .window
579 .renderer_mut()
580 .set_render_mode(graphics.render_mode.clone())
581 .unwrap();
582 }
583 },
584 SettingsChange::Interface(interface_change) => {
585 match interface_change {
586 Interface::Sct(sct) => {
587 settings.interface.sct = sct;
588 },
589 Interface::SctRoundDamage(sct_round_damage) => {
590 settings.interface.sct_damage_rounding = sct_round_damage;
591 },
592 Interface::SctDamageAccumDuration(sct_dmg_accum_duration) => {
593 settings.interface.sct_dmg_accum_duration = sct_dmg_accum_duration;
594 },
595 Interface::SctIncomingDamage(sct_inc_dmg) => {
596 settings.interface.sct_inc_dmg = sct_inc_dmg;
597 },
598 Interface::SctIncomingDamageAccumDuration(sct_inc_dmg_accum_duration) => {
599 settings.interface.sct_inc_dmg_accum_duration = sct_inc_dmg_accum_duration;
600 },
601 Interface::SpeechBubbleSelf(sbdm) => {
602 settings.interface.speech_bubble_self = sbdm;
603 },
604 Interface::SpeechBubbleDarkMode(sbdm) => {
605 settings.interface.speech_bubble_dark_mode = sbdm;
606 },
607 Interface::SpeechBubbleIcon(sbi) => {
608 settings.interface.speech_bubble_icon = sbi;
609 },
610 Interface::ToggleDebug(toggle_debug) => {
611 settings.interface.toggle_debug = toggle_debug;
612 },
613 Interface::ToggleHitboxes(toggle_hitboxes) => {
614 settings.interface.toggle_hitboxes = toggle_hitboxes;
615 },
616 Interface::ToggleChat(toggle_chat) => {
617 settings.interface.toggle_chat = toggle_chat;
618 },
619 Interface::ToggleTips(loading_tips) => {
620 settings.interface.loading_tips = loading_tips;
621 },
622 Interface::ToggleHotkeyHints(toggle_hotkey_hints) => {
623 settings.interface.toggle_hotkey_hints = toggle_hotkey_hints;
624 },
625 Interface::CrosshairTransp(crosshair_opacity) => {
626 settings.interface.crosshair_opacity = crosshair_opacity;
627 },
628 Interface::CrosshairType(crosshair_type) => {
629 settings.interface.crosshair_type = crosshair_type;
630 },
631 Interface::Intro(intro_show) => {
632 settings.interface.intro_show = intro_show;
633 },
634 Interface::ToggleXpBar(xp_bar) => {
635 settings.interface.xp_bar = xp_bar;
636 },
637 Interface::ToggleBarNumbers(bar_numbers) => {
638 settings.interface.bar_numbers = bar_numbers;
639 },
640 Interface::ToggleAlwaysShowBars(always_show_bars) => {
641 settings.interface.always_show_bars = always_show_bars;
642 },
643 Interface::TogglePoiseBar(enable_poise_bar) => {
644 settings.interface.enable_poise_bar = enable_poise_bar;
645 },
646 Interface::ToggleHealthPrefixes(use_health_prefixes) => {
647 settings.interface.use_health_prefixes = use_health_prefixes;
648 },
649 Interface::ToggleShortcutNumbers(shortcut_numbers) => {
650 settings.interface.shortcut_numbers = shortcut_numbers;
651 },
652 Interface::BuffPosition(buff_position) => {
653 settings.interface.buff_position = buff_position;
654 },
655 Interface::UiScale(scale_change) => {
656 settings.interface.ui_scale = session_state.hud.scale_change(scale_change);
657 },
658 Interface::MinimapShow(state) => {
659 settings.interface.minimap_show = state;
660 },
661 Interface::MinimapFaceNorth(state) => {
662 settings.interface.minimap_face_north = state;
663 },
664 Interface::MinimapZoom(minimap_zoom) => {
665 settings.interface.minimap_zoom = minimap_zoom;
666 },
667 Interface::MinimapScale(minimap_scale) => {
668 settings.interface.minimap_scale = minimap_scale;
669 },
670 Interface::MinimapColoredPlayerMarker(state) => {
671 settings.interface.minimap_colored_player_marker = state;
672 },
673 Interface::MapZoom(map_zoom) => {
674 settings.interface.map_zoom = map_zoom;
675 },
676 Interface::MapShowTopoMap(map_show_topo_map) => {
677 settings.interface.map_show_topo_map = map_show_topo_map;
678 },
679 Interface::MapShowDifficulty(map_show_difficulty) => {
680 settings.interface.map_show_difficulty = map_show_difficulty;
681 },
682 Interface::MapShowTowns(map_show_towns) => {
683 settings.interface.map_show_towns = map_show_towns;
684 },
685 Interface::MapShowDungeons(map_show_dungeons) => {
686 settings.interface.map_show_dungeons = map_show_dungeons;
687 },
688 Interface::MapShowCastles(map_show_castles) => {
689 settings.interface.map_show_castles = map_show_castles;
690 },
691 Interface::MapShowBridges(map_show_bridges) => {
692 settings.interface.map_show_bridges = map_show_bridges;
693 },
694 Interface::MapShowGliderCourses(map_show_glider_courses) => {
695 settings.interface.map_show_glider_courses = map_show_glider_courses;
696 },
697 Interface::MapShowCaves(map_show_caves) => {
698 settings.interface.map_show_caves = map_show_caves;
699 },
700 Interface::MapShowTrees(map_show_trees) => {
701 settings.interface.map_show_trees = map_show_trees;
702 },
703 Interface::MapShowPeaks(map_show_peaks) => {
704 settings.interface.map_show_peaks = map_show_peaks;
705 },
706 Interface::MapShowQuests(map_show_quests) => {
707 settings.interface.map_show_quests = map_show_quests;
708 },
709 Interface::MapShowBiomes(map_show_biomes) => {
710 settings.interface.map_show_biomes = map_show_biomes;
711 },
712 Interface::MapShowVoxelMap(map_show_voxel_map) => {
713 settings.interface.map_show_voxel_map = map_show_voxel_map;
714 },
715 Interface::AccumExperience(accum_experience) => {
716 settings.interface.accum_experience = accum_experience;
717 },
718 Interface::SlotsUsePrefixes(slots_use_prefixes) => {
719 settings.interface.slots_use_prefixes = slots_use_prefixes;
720 session_state.hud.set_slots_use_prefixes(slots_use_prefixes);
721 },
722 Interface::SlotsPrefixSwitchPoint(slots_prefix_switch_point) => {
723 settings.interface.slots_prefix_switch_point = slots_prefix_switch_point;
724 session_state
725 .hud
726 .set_slots_prefix_switch_point(slots_prefix_switch_point);
727 },
728 Interface::ResetInterfaceSettings => {
729 let tmp = settings.interface.intro_show;
731 settings.interface = InterfaceSettings::default();
732 settings.interface.intro_show = tmp;
733 session_state
735 .hud
736 .set_scaling_mode(settings.interface.ui_scale);
737 },
738 Interface::RowBackgroundOpacity(opacity) => {
739 settings.interface.row_background_opacity = opacity;
740 },
741 }
742 },
743 SettingsChange::Inventory(inventory_change) => match inventory_change {
744 Inventory::ChangeSortOrder(sort_order) => {
745 settings.inventory.sort_order = sort_order
746 },
747 },
748 SettingsChange::Language(language_change) => match language_change {
749 Language::ChangeLanguage(new_language) => {
750 settings.language.selected_language = new_language.language_identifier;
751 global_state.i18n =
752 LocalizationHandle::load_expect(&settings.language.selected_language);
753 global_state
754 .i18n
755 .set_english_fallback(settings.language.use_english_fallback);
756 session_state.hud.update_fonts(&global_state.i18n.read());
757 },
758 Language::ToggleEnglishFallback(toggle_fallback) => {
759 settings.language.use_english_fallback = toggle_fallback;
760 global_state
761 .i18n
762 .set_english_fallback(settings.language.use_english_fallback);
763 },
764 Language::ToggleSendToServer(share) => {
765 settings.language.send_to_server = share;
766 },
767 },
768 SettingsChange::Networking(networking_change) => match networking_change {
769 Networking::AdjustTerrainViewDistance(terrain_vd) => {
770 adjust_terrain_view_distance(terrain_vd, settings, session_state)
771 },
772 Networking::AdjustEntityViewDistance(entity_vd) => {
773 adjust_entity_view_distance(entity_vd, settings, session_state)
774 },
775 Networking::ChangePlayerPhysicsBehavior {
776 server_authoritative,
777 } => {
778 settings.networking.player_physics_behavior = server_authoritative;
779 session_state
780 .client
781 .borrow_mut()
782 .request_player_physics(server_authoritative);
783 },
784 Networking::ToggleLossyTerrainCompression(lossy_terrain_compression) => {
785 settings.networking.lossy_terrain_compression = lossy_terrain_compression;
786 session_state
787 .client
788 .borrow_mut()
789 .request_lossy_terrain_compression(lossy_terrain_compression);
790 },
791 #[cfg(feature = "discord")]
792 Networking::ToggleDiscordIntegration(enabled) => {
793 use crate::discord::Discord;
794
795 settings.networking.enable_discord_integration = enabled;
796 if enabled {
797 global_state.discord = Discord::start(&global_state.tokio_runtime);
798
799 #[cfg(feature = "singleplayer")]
800 let singleplayer = global_state.singleplayer.is_running();
801 #[cfg(not(feature = "singleplayer"))]
802 let singleplayer = false;
803
804 if singleplayer {
805 global_state.discord.join_singleplayer();
806 } else {
807 global_state.discord.join_server(
808 session_state.client.borrow().server_info().name.clone(),
809 );
810 }
811 } else {
812 global_state.discord.clear_activity();
813 global_state.discord = Discord::Inactive;
814 }
815 },
816 },
817 SettingsChange::Accessibility(accessibility_change) => match accessibility_change {
818 Accessibility::ChangeRenderMode(new_render_mode) => {
819 change_render_mode(*new_render_mode, &mut global_state.window, settings);
820 },
821 Accessibility::SetSubtitles(enabled) => {
822 global_state.settings.audio.subtitles = enabled;
823 global_state.audio.set_subtitles(enabled);
824 },
825 },
826 }
827 global_state
828 .settings
829 .save_to_file_warn(&global_state.config_dir);
830 }
831}
832
833use crate::settings::Settings;
834
835pub fn change_render_mode(
836 new_render_mode: RenderMode,
837 window: &mut Window,
838 settings: &mut Settings,
839) {
840 window
842 .renderer_mut()
843 .set_render_mode(new_render_mode.clone())
844 .unwrap();
845 settings.graphics.render_mode = new_render_mode;
846}
847
848fn adjust_terrain_view_distance(
849 terrain_vd: u32,
850 settings: &mut Settings,
851 session_state: &mut SessionState,
852) {
853 settings.graphics.terrain_view_distance = terrain_vd;
854 client_set_view_distance(settings, session_state);
855}
856
857fn adjust_entity_view_distance(
858 entity_vd: u32,
859 settings: &mut Settings,
860 session_state: &mut SessionState,
861) {
862 settings.graphics.entity_view_distance = entity_vd;
863 client_set_view_distance(settings, session_state);
864}
865
866fn client_set_view_distance(settings: &Settings, session_state: &mut SessionState) {
867 let view_distances = common::ViewDistances {
868 terrain: settings.graphics.terrain_view_distance,
869 entity: settings.graphics.entity_view_distance,
870 };
871 session_state
872 .client
873 .borrow_mut()
874 .set_view_distances(view_distances);
875}