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