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