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