veloren_voxygen/session/
settings_change.rs

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