From db7d0af951ed7a19e29918c8a517fecb82a30c15 Mon Sep 17 00:00:00 2001 From: Avi Weinstock Date: Sun, 21 Mar 2021 15:32:59 -0400 Subject: [PATCH 1/2] Add a vertical camera clamp option and toggle to voxygen. --- assets/voxygen/i18n/en/gameinput.ron | 1 + assets/voxygen/i18n/en/hud/hud_settings.ron | 2 + assets/voxygen/i18n/en/hud/misc.ron | 1 + voxygen/src/hud/mod.rs | 101 ++++++++++++++++---- voxygen/src/hud/settings_window.rs | 78 ++++++++++++++- voxygen/src/session.rs | 72 ++++++++------ voxygen/src/settings.rs | 5 + voxygen/src/window.rs | 3 + 8 files changed, 212 insertions(+), 51 deletions(-) diff --git a/assets/voxygen/i18n/en/gameinput.ron b/assets/voxygen/i18n/en/gameinput.ron index 410f6cd800..4e7aa35c2e 100644 --- a/assets/voxygen/i18n/en/gameinput.ron +++ b/assets/voxygen/i18n/en/gameinput.ron @@ -51,6 +51,7 @@ "gameinput.interact": "Interact", "gameinput.freelook": "Free Look", "gameinput.autowalk": "Auto Walk", + "gameinput.cameraclamp": "Camera Clamp", "gameinput.dance": "Dance", "gameinput.select": "Select Entity", "gameinput.acceptgroupinvite": "Accept Group Invite", diff --git a/assets/voxygen/i18n/en/hud/hud_settings.ron b/assets/voxygen/i18n/en/hud/hud_settings.ron index ee1ea0ed7d..23f3b83899 100644 --- a/assets/voxygen/i18n/en/hud/hud_settings.ron +++ b/assets/voxygen/i18n/en/hud/hud_settings.ron @@ -40,12 +40,14 @@ "hud.settings.pan_sensitivity": "Pan Sensitivity", "hud.settings.zoom_sensitivity": "Zoom Sensitivity", + "hud.settings.camera_clamp_angle": "Angle for vertical camera clamp mode", "hud.settings.invert_scroll_zoom": "Invert Scroll Zoom", "hud.settings.invert_mouse_y_axis": "Invert Mouse Y Axis", "hud.settings.invert_controller_y_axis": "Invert Controller Y Axis", "hud.settings.enable_mouse_smoothing": "Camera Smoothing", "hud.settings.free_look_behavior": "Free look behavior", "hud.settings.auto_walk_behavior": "Auto walk behavior", + "hud.settings.camera_clamp_behavior": "Camera clamp behavior", "hud.settings.stop_auto_walk_on_input": "Stop auto walk on movement", "hud.settings.reset_gameplay": "Reset to Defaults", diff --git a/assets/voxygen/i18n/en/hud/misc.ron b/assets/voxygen/i18n/en/hud/misc.ron index 77b31b9eff..d04ef2750e 100644 --- a/assets/voxygen/i18n/en/hud/misc.ron +++ b/assets/voxygen/i18n/en/hud/misc.ron @@ -43,6 +43,7 @@ Whenever you feel ready, try to get even better equipment from the many challeng "hud.diary": "Diary", "hud.free_look_indicator": "Free look active. Press {key} to disable.", + "hud.camera_clamp_indicator": "Camera vertical clamp active. Press {key} to disable.", "hud.auto_walk_indicator": "Auto walk active", }, diff --git a/voxygen/src/hud/mod.rs b/voxygen/src/hud/mod.rs index 8d3f23e9b5..3b77b718ba 100644 --- a/voxygen/src/hud/mod.rs +++ b/voxygen/src/hud/mod.rs @@ -272,6 +272,10 @@ widget_ids! { auto_walk_txt, auto_walk_bg, + // Auto walk indicator + camera_clamp_txt, + camera_clamp_bg, + // Tutorial quest_bg, q_headline_bg, @@ -345,6 +349,7 @@ pub enum Event { SendMessage(String), AdjustMousePan(u32), AdjustMouseZoom(u32), + AdjustCameraClamp(u32), ToggleZoomInvert(bool), ToggleMouseYInvert(bool), ToggleControllerYInvert(bool), @@ -421,6 +426,7 @@ pub enum Event { ChangeFreeLookBehavior(PressBehavior), ChangeRenderMode(Box), ChangeAutoWalkBehavior(PressBehavior), + ChangeCameraClampBehavior(PressBehavior), ChangeStopAutoWalkOnInput(bool), CraftRecipe(String), InviteMember(Uid), @@ -494,6 +500,25 @@ pub enum PressBehavior { Toggle = 0, } +impl PressBehavior { + pub fn update(&self, keystate: bool, setting: &mut bool, f: impl FnOnce(bool)) { + match (self, keystate) { + // flip the state on key press in toggle mode + (PressBehavior::Toggle, true) => { + *setting ^= true; + f(*setting); + }, + // do nothing on key release in toggle mode + (PressBehavior::Toggle, false) => {}, + // set the setting to the key state in hold mode + (PressBehavior::Hold, state) => { + *setting = state; + f(*setting); + }, + } + } +} + pub struct Show { ui: bool, intro: bool, @@ -518,6 +543,7 @@ pub struct Show { stats: bool, free_look: bool, auto_walk: bool, + camera_clamp: bool, prompt_dialog: Option, } impl Show { @@ -835,6 +861,7 @@ impl Hud { stats: false, free_look: false, auto_walk: false, + camera_clamp: false, prompt_dialog: None, }, to_focus: None, @@ -2456,6 +2483,9 @@ impl Hud { settings_window::Event::AdjustMouseZoom(sensitivity) => { events.push(Event::AdjustMouseZoom(sensitivity)); }, + settings_window::Event::AdjustCameraClamp(sensitivity) => { + events.push(Event::AdjustCameraClamp(sensitivity)); + }, settings_window::Event::ChatTransp(chat_transp) => { events.push(Event::ChatTransp(chat_transp)); }, @@ -2552,6 +2582,9 @@ impl Hud { settings_window::Event::ChangeAutoWalkBehavior(behavior) => { events.push(Event::ChangeAutoWalkBehavior(behavior)); }, + settings_window::Event::ChangeCameraClampBehavior(behavior) => { + events.push(Event::ChangeCameraClampBehavior(behavior)); + }, settings_window::Event::ChangeStopAutoWalkOnInput(state) => { events.push(Event::ChangeStopAutoWalkOnInput(state)); }, @@ -2737,6 +2770,8 @@ impl Hud { } } + let mut indicator_offset = 40.0; + // Free look indicator if let Some(freelook_key) = global_state .settings @@ -2744,26 +2779,22 @@ impl Hud { .get_binding(GameInput::FreeLook) { if self.show.free_look { - Text::new( - &i18n - .get("hud.free_look_indicator") - .replace("{key}", freelook_key.to_string().as_str()), - ) - .color(TEXT_BG) - .mid_top_with_margin_on(ui_widgets.window, 40.0) - .font_id(self.fonts.cyri.conrod_id) - .font_size(self.fonts.cyri.scale(20)) - .set(self.ids.free_look_bg, ui_widgets); - Text::new( - &i18n - .get("hud.free_look_indicator") - .replace("{key}", freelook_key.to_string().as_str()), - ) - .color(KILL_COLOR) - .top_left_with_margins_on(self.ids.free_look_bg, -1.0, -1.0) - .font_id(self.fonts.cyri.conrod_id) - .font_size(self.fonts.cyri.scale(20)) - .set(self.ids.free_look_txt, ui_widgets); + let msg = i18n + .get("hud.free_look_indicator") + .replace("{key}", freelook_key.to_string().as_str()); + Text::new(&msg) + .color(TEXT_BG) + .mid_top_with_margin_on(ui_widgets.window, indicator_offset) + .font_id(self.fonts.cyri.conrod_id) + .font_size(self.fonts.cyri.scale(20)) + .set(self.ids.free_look_bg, ui_widgets); + indicator_offset += 30.0; + Text::new(&msg) + .color(KILL_COLOR) + .top_left_with_margins_on(self.ids.free_look_bg, -1.0, -1.0) + .font_id(self.fonts.cyri.conrod_id) + .font_size(self.fonts.cyri.scale(20)) + .set(self.ids.free_look_txt, ui_widgets); } }; @@ -2771,10 +2802,11 @@ impl Hud { if self.show.auto_walk { Text::new(i18n.get("hud.auto_walk_indicator")) .color(TEXT_BG) - .mid_top_with_margin_on(ui_widgets.window, 70.0) + .mid_top_with_margin_on(ui_widgets.window, indicator_offset) .font_id(self.fonts.cyri.conrod_id) .font_size(self.fonts.cyri.scale(20)) .set(self.ids.auto_walk_bg, ui_widgets); + indicator_offset += 30.0; Text::new(i18n.get("hud.auto_walk_indicator")) .color(KILL_COLOR) .top_left_with_margins_on(self.ids.auto_walk_bg, -1.0, -1.0) @@ -2783,6 +2815,31 @@ impl Hud { .set(self.ids.auto_walk_txt, ui_widgets); } + // Camera clamp indicator + if let Some(cameraclamp_key) = global_state + .settings + .controls + .get_binding(GameInput::CameraClamp) + { + if self.show.camera_clamp { + let msg = i18n + .get("hud.camera_clamp_indicator") + .replace("{key}", cameraclamp_key.to_string().as_str()); + Text::new(&msg) + .color(TEXT_BG) + .mid_top_with_margin_on(ui_widgets.window, indicator_offset) + .font_id(self.fonts.cyri.conrod_id) + .font_size(self.fonts.cyri.scale(20)) + .set(self.ids.camera_clamp_bg, ui_widgets); + Text::new(&msg) + .color(KILL_COLOR) + .top_left_with_margins_on(self.ids.camera_clamp_bg, -1.0, -1.0) + .font_id(self.fonts.cyri.conrod_id) + .font_size(self.fonts.cyri.scale(20)) + .set(self.ids.camera_clamp_txt, ui_widgets); + } + } + // Maintain slot manager for event in self.slot_manager.maintain(ui_widgets) { use comp::slot::Slot; @@ -3233,6 +3290,8 @@ impl Hud { pub fn auto_walk(&mut self, auto_walk: bool) { self.show.auto_walk = auto_walk; } + pub fn camera_clamp(&mut self, camera_clamp: bool) { self.show.camera_clamp = camera_clamp; } + pub fn handle_outcome(&mut self, outcome: &Outcome) { match outcome { Outcome::ExpChange { uid, exp } => self.exp_floaters.push(ExpFloater { diff --git a/voxygen/src/hud/settings_window.rs b/voxygen/src/hud/settings_window.rs index 95cd907c50..e94cac45de 100644 --- a/voxygen/src/hud/settings_window.rs +++ b/voxygen/src/hud/settings_window.rs @@ -97,6 +97,9 @@ widget_ids! { mouse_zoom_value, mouse_zoom_invert_button, mouse_zoom_invert_label, + camera_clamp_slider, + camera_clamp_label, + camera_clamp_value, mouse_y_invert_button, mouse_y_invert_label, controller_y_invert_button, @@ -236,6 +239,8 @@ widget_ids! { free_look_behavior_list, auto_walk_behavior_text, auto_walk_behavior_list, + camera_clamp_behavior_text, + camera_clamp_behavior_list, stop_auto_walk_on_input_button, stop_auto_walk_on_input_label, } @@ -303,6 +308,7 @@ pub enum Event { Close, AdjustMousePan(u32), AdjustMouseZoom(u32), + AdjustCameraClamp(u32), ToggleZoomInvert(bool), ToggleMouseYInvert(bool), ToggleControllerYInvert(bool), @@ -342,6 +348,7 @@ pub enum Event { ResetAudioSettings, ChangeFreeLookBehavior(PressBehavior), ChangeAutoWalkBehavior(PressBehavior), + ChangeCameraClampBehavior(PressBehavior), ChangeStopAutoWalkOnInput(bool), } @@ -1367,6 +1374,7 @@ impl<'a> Widget for SettingsWindow<'a> { if let SettingsTab::Gameplay = self.show.settings_tab { let display_pan = self.global_state.settings.gameplay.pan_sensitivity; let display_zoom = self.global_state.settings.gameplay.zoom_sensitivity; + let display_clamp = self.global_state.settings.gameplay.camera_clamp_angle; // Mouse Pan Sensitivity Text::new(&self.localized_strings.get("hud.settings.pan_sensitivity")) @@ -1432,6 +1440,42 @@ impl<'a> Widget for SettingsWindow<'a> { .color(TEXT_COLOR) .set(state.ids.mouse_zoom_value, ui); + // Camera clamp angle + Text::new( + &self + .localized_strings + .get("hud.settings.camera_clamp_angle"), + ) + .down_from(state.ids.mouse_zoom_slider, 10.0) + .font_size(self.fonts.cyri.scale(14)) + .font_id(self.fonts.cyri.conrod_id) + .color(TEXT_COLOR) + .set(state.ids.camera_clamp_label, ui); + + if let Some(new_val) = ImageSlider::discrete( + display_clamp, + 1, + 90, + self.imgs.slider_indicator, + self.imgs.slider, + ) + .w_h(550.0, 22.0) + .down_from(state.ids.camera_clamp_label, 10.0) + .track_breadth(30.0) + .slider_length(10.0) + .pad_track((5.0, 5.0)) + .set(state.ids.camera_clamp_slider, ui) + { + events.push(Event::AdjustCameraClamp(new_val)); + } + + Text::new(&format!("{}", display_clamp)) + .right_from(state.ids.camera_clamp_slider, 8.0) + .font_size(self.fonts.cyri.scale(14)) + .font_id(self.fonts.cyri.conrod_id) + .color(TEXT_COLOR) + .set(state.ids.camera_clamp_value, ui); + // Zoom Inversion let zoom_inverted = ToggleButton::new( self.global_state.settings.gameplay.zoom_inversion, @@ -1439,7 +1483,7 @@ impl<'a> Widget for SettingsWindow<'a> { self.imgs.checkbox_checked, ) .w_h(18.0, 18.0) - .down_from(state.ids.mouse_zoom_slider, 20.0) + .down_from(state.ids.camera_clamp_slider, 20.0) .hover_images(self.imgs.checkbox_mo, self.imgs.checkbox_checked_mo) .press_images(self.imgs.checkbox_press, self.imgs.checkbox_checked) .set(state.ids.mouse_zoom_invert_button, ui); @@ -1622,6 +1666,36 @@ impl<'a> Widget for SettingsWindow<'a> { } } + // Camera clamp behavior + Text::new( + &self + .localized_strings + .get("hud.settings.camera_clamp_behavior"), + ) + .down_from(state.ids.free_look_behavior_list, 10.0) + .font_size(self.fonts.cyri.scale(14)) + .font_id(self.fonts.cyri.conrod_id) + .color(TEXT_COLOR) + .set(state.ids.camera_clamp_behavior_text, ui); + + let camera_clamp_selected = + self.global_state.settings.gameplay.camera_clamp_behavior as usize; + + if let Some(clicked) = DropDownList::new(&mode_label_list, Some(camera_clamp_selected)) + .w_h(200.0, 30.0) + .color(MENU_BG) + .label_color(TEXT_COLOR) + .label_font_id(self.fonts.cyri.conrod_id) + .down_from(state.ids.camera_clamp_behavior_text, 8.0) + .set(state.ids.camera_clamp_behavior_list, ui) + { + match clicked { + 0 => events.push(Event::ChangeCameraClampBehavior(PressBehavior::Toggle)), + 1 => events.push(Event::ChangeCameraClampBehavior(PressBehavior::Hold)), + _ => unreachable!(), + } + } + // Stop autowalk on input toggle let stop_auto_walk_on_input_toggle = ToggleButton::new( self.global_state.settings.gameplay.stop_auto_walk_on_input, @@ -1659,7 +1733,7 @@ impl<'a> Widget for SettingsWindow<'a> { .w_h(RESET_BUTTONS_WIDTH, RESET_BUTTONS_HEIGHT) .hover_image(self.imgs.button_hover) .press_image(self.imgs.button_press) - .down_from(state.ids.free_look_behavior_list, 12.0) + .down_from(state.ids.camera_clamp_behavior_list, 12.0) .label(&self.localized_strings.get("hud.settings.reset_gameplay")) .label_font_size(self.fonts.cyri.scale(14)) .label_color(TEXT_COLOR) diff --git a/voxygen/src/session.rs b/voxygen/src/session.rs index 879d440d4e..48cac17725 100644 --- a/voxygen/src/session.rs +++ b/voxygen/src/session.rs @@ -34,7 +34,7 @@ use common_net::{ use crate::{ audio::sfx::SfxEvent, controller::ControllerSettings, - hud::{DebugInfo, Event as HudEvent, Hud, HudInfo, PressBehavior, PromptDialogSettings}, + hud::{DebugInfo, Event as HudEvent, Hud, HudInfo, PromptDialogSettings}, i18n::{i18n_asset_key, Localization}, key_state::KeyState, menu::char_selection::CharSelectionState, @@ -69,6 +69,7 @@ pub struct SessionState { freefly_vel: Vec3, free_look: bool, auto_walk: bool, + camera_clamp: bool, is_aiming: bool, target_entity: Option, selected_entity: Option<(specs::Entity, std::time::Instant)>, @@ -106,6 +107,7 @@ impl SessionState { freefly_vel: Vec3::zero(), free_look: false, auto_walk: false, + camera_clamp: false, is_aiming: false, target_entity: None, selected_entity: None, @@ -267,10 +269,20 @@ impl PlayState for SessionState { (client.presence(), client.registered()) }; if client_presence.is_some() { + let camera = self.scene.camera_mut(); + + // Clamp camera's vertical angle if the toggle is enabled + if self.camera_clamp { + let mut cam_dir = camera.get_orientation(); + let cam_dir_clamp = global_state.settings.gameplay.camera_clamp_angle as f32 + * std::f32::consts::PI + / 180.0; + cam_dir.y = (-cam_dir_clamp).max(cam_dir.y).min(cam_dir_clamp); + camera.set_orientation(cam_dir); + } + // Compute camera data - self.scene - .camera_mut() - .compute_dependents(&*self.client.borrow().state().terrain()); + camera.compute_dependents(&*self.client.borrow().state().terrain()); let camera::Dependents { cam_pos, cam_dir, .. } = self.scene.camera().dependents(); @@ -608,32 +620,29 @@ impl PlayState for SessionState { } }, GameInput::FreeLook => { - match (global_state.settings.gameplay.free_look_behavior, state) { - (PressBehavior::Toggle, true) => { - self.free_look = !self.free_look; - self.hud.free_look(self.free_look); - }, - (PressBehavior::Hold, state) => { - self.free_look = state; - self.hud.free_look(self.free_look); - }, - _ => {}, - }; + let hud = &mut self.hud; + global_state.settings.gameplay.free_look_behavior.update( + state, + &mut self.free_look, + |b| hud.free_look(b), + ); }, GameInput::AutoWalk => { - match (global_state.settings.gameplay.auto_walk_behavior, state) { - (PressBehavior::Toggle, true) => { - self.auto_walk = !self.auto_walk; - self.key_state.auto_walk = self.auto_walk; - self.hud.auto_walk(self.auto_walk); - }, - (PressBehavior::Hold, state) => { - self.auto_walk = state; - self.key_state.auto_walk = self.auto_walk; - self.hud.auto_walk(self.auto_walk); - }, - _ => {}, - } + let hud = &mut self.hud; + global_state.settings.gameplay.auto_walk_behavior.update( + state, + &mut self.auto_walk, + |b| hud.auto_walk(b), + ); + self.key_state.auto_walk = self.auto_walk; + }, + GameInput::CameraClamp => { + let hud = &mut self.hud; + global_state.settings.gameplay.camera_clamp_behavior.update( + state, + &mut self.camera_clamp, + |b| hud.camera_clamp(b), + ); }, GameInput::CycleCamera if state => { // Prevent accessing camera modes which aren't available in @@ -880,6 +889,10 @@ impl PlayState for SessionState { global_state.settings.gameplay.zoom_sensitivity = sensitivity; global_state.settings.save_to_file_warn(); }, + HudEvent::AdjustCameraClamp(angle) => { + global_state.settings.gameplay.camera_clamp_angle = angle; + global_state.settings.save_to_file_warn(); + }, HudEvent::ToggleZoomInvert(zoom_inverted) => { global_state.window.zoom_inversion = zoom_inverted; global_state.settings.gameplay.zoom_inversion = zoom_inverted; @@ -1348,6 +1361,9 @@ impl PlayState for SessionState { HudEvent::ChangeAutoWalkBehavior(behavior) => { global_state.settings.gameplay.auto_walk_behavior = behavior; }, + HudEvent::ChangeCameraClampBehavior(behavior) => { + global_state.settings.gameplay.camera_clamp_behavior = behavior; + }, HudEvent::ChangeStopAutoWalkOnInput(state) => { global_state.settings.gameplay.stop_auto_walk_on_input = state; }, diff --git a/voxygen/src/settings.rs b/voxygen/src/settings.rs index 72b8f5fce7..f55ca48a3d 100644 --- a/voxygen/src/settings.rs +++ b/voxygen/src/settings.rs @@ -159,6 +159,7 @@ impl ControlSettings { GameInput::ToggleWield => KeyMouse::Key(VirtualKeyCode::T), GameInput::FreeLook => KeyMouse::Key(VirtualKeyCode::L), GameInput::AutoWalk => KeyMouse::Key(VirtualKeyCode::Period), + GameInput::CameraClamp => KeyMouse::Key(VirtualKeyCode::Apostrophe), GameInput::CycleCamera => KeyMouse::Key(VirtualKeyCode::Key0), GameInput::Slot1 => KeyMouse::Key(VirtualKeyCode::Key1), GameInput::Slot2 => KeyMouse::Key(VirtualKeyCode::Key2), @@ -494,11 +495,13 @@ impl Default for InterfaceSettings { pub struct GameplaySettings { pub pan_sensitivity: u32, pub zoom_sensitivity: u32, + pub camera_clamp_angle: u32, pub zoom_inversion: bool, pub mouse_y_inversion: bool, pub smooth_pan_enable: bool, pub free_look_behavior: PressBehavior, pub auto_walk_behavior: PressBehavior, + pub camera_clamp_behavior: PressBehavior, pub stop_auto_walk_on_input: bool, } @@ -507,11 +510,13 @@ impl Default for GameplaySettings { Self { pan_sensitivity: 100, zoom_sensitivity: 100, + camera_clamp_angle: 45, zoom_inversion: false, mouse_y_inversion: false, smooth_pan_enable: false, free_look_behavior: PressBehavior::Toggle, auto_walk_behavior: PressBehavior::Toggle, + camera_clamp_behavior: PressBehavior::Toggle, stop_auto_walk_on_input: true, } } diff --git a/voxygen/src/window.rs b/voxygen/src/window.rs index 93db970855..66f409a0d4 100644 --- a/voxygen/src/window.rs +++ b/voxygen/src/window.rs @@ -71,6 +71,7 @@ pub enum GameInput { SwapLoadout, FreeLook, AutoWalk, + CameraClamp, CycleCamera, Select, AcceptGroupInvite, @@ -122,6 +123,7 @@ impl GameInput { GameInput::ToggleWield => "gameinput.togglewield", GameInput::FreeLook => "gameinput.freelook", GameInput::AutoWalk => "gameinput.autowalk", + GameInput::CameraClamp => "gameinput.cameraclamp", GameInput::Slot1 => "gameinput.slot1", GameInput::Slot2 => "gameinput.slot2", GameInput::Slot3 => "gameinput.slot3", @@ -182,6 +184,7 @@ impl GameInput { GameInput::ToggleWield, GameInput::FreeLook, GameInput::AutoWalk, + GameInput::CameraClamp, GameInput::Slot1, GameInput::Slot2, GameInput::Slot3, From 761435e0fcdfafccf1399353074e9a7b2a01decf Mon Sep 17 00:00:00 2001 From: Avi Weinstock Date: Tue, 23 Mar 2021 18:41:13 -0400 Subject: [PATCH 2/2] Address MR 1962 review comments. --- voxygen/src/hud/mod.rs | 2 +- voxygen/src/session.rs | 9 ++++++--- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/voxygen/src/hud/mod.rs b/voxygen/src/hud/mod.rs index 3b77b718ba..1d7288071d 100644 --- a/voxygen/src/hud/mod.rs +++ b/voxygen/src/hud/mod.rs @@ -272,7 +272,7 @@ widget_ids! { auto_walk_txt, auto_walk_bg, - // Auto walk indicator + // Camera clamp indicator camera_clamp_txt, camera_clamp_bg, diff --git a/voxygen/src/session.rs b/voxygen/src/session.rs index 48cac17725..9c403a42e0 100644 --- a/voxygen/src/session.rs +++ b/voxygen/src/session.rs @@ -274,9 +274,8 @@ impl PlayState for SessionState { // Clamp camera's vertical angle if the toggle is enabled if self.camera_clamp { let mut cam_dir = camera.get_orientation(); - let cam_dir_clamp = global_state.settings.gameplay.camera_clamp_angle as f32 - * std::f32::consts::PI - / 180.0; + let cam_dir_clamp = + (global_state.settings.gameplay.camera_clamp_angle as f32).to_radians(); cam_dir.y = (-cam_dir_clamp).max(cam_dir.y).min(cam_dir_clamp); camera.set_orientation(cam_dir); } @@ -1357,15 +1356,19 @@ impl PlayState for SessionState { }, HudEvent::ChangeFreeLookBehavior(behavior) => { global_state.settings.gameplay.free_look_behavior = behavior; + global_state.settings.save_to_file_warn(); }, HudEvent::ChangeAutoWalkBehavior(behavior) => { global_state.settings.gameplay.auto_walk_behavior = behavior; + global_state.settings.save_to_file_warn(); }, HudEvent::ChangeCameraClampBehavior(behavior) => { global_state.settings.gameplay.camera_clamp_behavior = behavior; + global_state.settings.save_to_file_warn(); }, HudEvent::ChangeStopAutoWalkOnInput(state) => { global_state.settings.gameplay.stop_auto_walk_on_input = state; + global_state.settings.save_to_file_warn(); }, HudEvent::CraftRecipe(r) => { self.client.borrow_mut().craft_recipe(&r);