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