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