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 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 ToggleDraggableWindows(bool),
148 ToggleTips(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::ToggleDraggableWindows(toggle_draggable_windows) => {
693 settings.interface.toggle_draggable_windows = toggle_draggable_windows;
694 },
695 Interface::ToggleTips(loading_tips) => {
696 settings.interface.loading_tips = loading_tips;
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 settings.hud_position = HudPositionSettings::default();
808 session_state
810 .hud
811 .set_scaling_mode(settings.interface.ui_scale);
812 },
813 Interface::RowBackgroundOpacity(opacity) => {
814 settings.interface.row_background_opacity = opacity;
815 },
816 }
817 },
818 SettingsChange::Inventory(inventory_change) => match inventory_change {
819 Inventory::ChangeSortOrder(sort_order) => {
820 settings.inventory.sort_order = sort_order
821 },
822 },
823 SettingsChange::Language(language_change) => match language_change {
824 Language::ChangeLanguage(new_language) => {
825 settings.language.selected_language = new_language.language_identifier;
826 global_state.i18n =
827 LocalizationHandle::load_expect(&settings.language.selected_language);
828 global_state
829 .i18n
830 .set_english_fallback(settings.language.use_english_fallback);
831 session_state.hud.update_fonts(&global_state.i18n.read());
832 },
833 Language::ToggleEnglishFallback(toggle_fallback) => {
834 settings.language.use_english_fallback = toggle_fallback;
835 global_state
836 .i18n
837 .set_english_fallback(settings.language.use_english_fallback);
838 },
839 Language::ToggleSendToServer(share) => {
840 settings.language.send_to_server = share;
841 },
842 },
843 SettingsChange::Networking(networking_change) => match networking_change {
844 Networking::AdjustTerrainViewDistance(terrain_vd) => {
845 adjust_terrain_view_distance(terrain_vd, settings, session_state)
846 },
847 Networking::AdjustEntityViewDistance(entity_vd) => {
848 adjust_entity_view_distance(entity_vd, settings, session_state)
849 },
850 Networking::ChangePlayerPhysicsBehavior {
851 server_authoritative,
852 } => {
853 settings.networking.player_physics_behavior = server_authoritative;
854 session_state
855 .client
856 .borrow_mut()
857 .request_player_physics(server_authoritative);
858 },
859 Networking::ToggleLossyTerrainCompression(lossy_terrain_compression) => {
860 settings.networking.lossy_terrain_compression = lossy_terrain_compression;
861 session_state
862 .client
863 .borrow_mut()
864 .request_lossy_terrain_compression(lossy_terrain_compression);
865 },
866 #[cfg(feature = "discord")]
867 Networking::ToggleDiscordIntegration(enabled) => {
868 use crate::discord::Discord;
869
870 settings.networking.enable_discord_integration = enabled;
871 if enabled {
872 global_state.discord = Discord::start(&global_state.tokio_runtime);
873
874 #[cfg(feature = "singleplayer")]
875 let singleplayer = global_state.singleplayer.is_running();
876 #[cfg(not(feature = "singleplayer"))]
877 let singleplayer = false;
878
879 if singleplayer {
880 global_state.discord.join_singleplayer();
881 } else {
882 global_state.discord.join_server(
883 session_state.client.borrow().server_info().name.clone(),
884 );
885 }
886 } else {
887 global_state.discord.clear_activity();
888 global_state.discord = Discord::Inactive;
889 }
890 },
891 },
892 SettingsChange::Accessibility(accessibility_change) => match accessibility_change {
893 Accessibility::ChangeRenderMode(new_render_mode) => {
894 change_render_mode(*new_render_mode, &mut global_state.window, settings);
895 },
896 Accessibility::SetSubtitles(enabled) => {
897 global_state.settings.audio.subtitles = enabled;
898 global_state.audio.set_subtitles(enabled);
899 },
900 },
901 }
902 global_state
903 .settings
904 .save_to_file_warn(&global_state.config_dir);
905 }
906}
907
908use crate::settings::Settings;
909
910pub fn change_render_mode(
911 new_render_mode: RenderMode,
912 window: &mut Window,
913 settings: &mut Settings,
914) {
915 window
917 .renderer_mut()
918 .set_render_mode(new_render_mode.clone())
919 .unwrap();
920 settings.graphics.render_mode = new_render_mode;
921}
922
923fn adjust_terrain_view_distance(
924 terrain_vd: u32,
925 settings: &mut Settings,
926 session_state: &mut SessionState,
927) {
928 settings.graphics.terrain_view_distance = terrain_vd;
929 client_set_view_distance(settings, session_state);
930}
931
932fn adjust_entity_view_distance(
933 entity_vd: u32,
934 settings: &mut Settings,
935 session_state: &mut SessionState,
936) {
937 settings.graphics.entity_view_distance = entity_vd;
938 client_set_view_distance(settings, session_state);
939}
940
941fn client_set_view_distance(settings: &Settings, session_state: &mut SessionState) {
942 let view_distances = common::ViewDistances {
943 terrain: settings.graphics.terrain_view_distance,
944 entity: settings.graphics.entity_view_distance,
945 };
946 session_state
947 .client
948 .borrow_mut()
949 .set_view_distances(view_distances);
950}