Allow locking camera zoom

Allow the camera's zoom to be locked by a keybind
	or a Gameplay setting. The zoom lock
	behavior can be changed between Toggle
	and Auto, where Auto only locks the camera
	zoom while specific movement/combat inputs
	are being pressed. (closes !1528)

A temporary fading notification is shown at the
	top of the screen, informing the player of
	the setting change (when the keybind is
	used) or that the zoom is locked (when
	the player might have forgotten the zoom
	is locked, and is trying to zoom).

i18n strings are added for English and German,
	but no other languages.

To implement the simplistic fading text, the
	behavior was extracted into an impl
	called `ChangeNotification`, where
	reasons are quantified by `NotificationReason`.
This commit is contained in:
Cat Stevens 2023-02-20 20:55:49 -05:00
parent 9a025cfcc8
commit 83e4cdfe76
15 changed files with 347 additions and 7 deletions

View File

@ -18,6 +18,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Unlockable door blocks.
- Sprite rotation for Spots.
- Better entity placement options for spots.
- Camera zoom can now be locked, to prevent accidental zooming while rolling in combat. It comes
with a keybind to enable/disable the setting, and an Auto/Toggle behavior setting. Auto behavior
will only lock the camera zoom while movement and combat inputs are also being pressed.
### Changed
- Bats move slower and use a simple proportional controller to maintain altitude

View File

@ -49,6 +49,7 @@ gameinput-togglewield = Waffe ziehen/wegstecken
gameinput-interact = Interagieren
gameinput-freelook = Freie Sicht
gameinput-autowalk = Automatisch Laufen/Schwimmen
gameinput-zoomlock = Kamera-Zoomsperre
gameinput-cameraclamp = Kamera fixieren
gameinput-dance = Tanzen
gameinput-select = Einheit auswählen

View File

@ -35,6 +35,9 @@ hud-diary = Tagebuch
hud-free_look_indicator = Freie Sicht aktiv. Drücke { $key } zum deaktivieren.
hud-camera_clamp_indicator = Vertikale Kamerafixierung aktiv. Drücke { $key } zum deaktivieren.
hud-auto_walk_indicator = Auto Laufen/Schwimmen aktiv
hud-zoom_lock_indicator-remind = Zoom gesperrt
hud-zoom_lock_indicator-enable = Kamerazoom gesperrt
hud-zoom_lock_indicator-disable = Kamerazoom entsperrt
hud-collect = Aufsammeln
hud-pick_up = Aufheben
hud-open = Öffnen

View File

@ -2,6 +2,8 @@ hud-settings-general = Allgemein
hud-settings-none = Keine
hud-settings-press_behavior-toggle = Umschalten
hud-settings-press_behavior-hold = Halten
hud-settings-autopress_behavior-toggle = Umschalten
hud-settings-autopress_behavior-auto = Auto
hud-settings-help_window = Hilfe zu Fenstern
hud-settings-debug_info = Debug-Informationen
hud-settings-show_hitboxes = Hitboxen anzeigen
@ -50,10 +52,12 @@ hud-settings-enable_mouse_smoothing = Kamera-Glättung
hud-settings-free_look_behavior = Verhalten bei freiem Kameramodus
hud-settings-auto_walk_behavior = Verhalten bei automatischem Gehen
hud-settings-camera_clamp_behavior = Verhalten bei starrer Kamera
hud-settings-zoom_lock_behavior = Verhalten bei Kamera-Zoomsperre
hud-settings-player_physics_behavior = Spielerphysik (experimentell)
hud-settings-stop_auto_walk_on_input = Automatisches Gehen bei Spieleraktivität anhalten
hud-settings-auto_camera = Auto Kamera
hud-settings-bow_zoom = Hinein zoomen, wenn der Bogen aufgeladen wird
hud-settings-zoom_lock = Kamera-Zoomsperre
hud-settings-reset_gameplay =
Einstellungen
zurücksetzen

View File

@ -49,6 +49,7 @@ gameinput-togglewield = Toggle Wield
gameinput-interact = Interact
gameinput-freelook = Free Look
gameinput-autowalk = Auto Walk/Swim
gameinput-zoomlock = Camera zoom lock
gameinput-cameraclamp = Camera Clamp
gameinput-dance = Dance
gameinput-select = Select Entity

View File

@ -35,6 +35,9 @@ 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/swim active
hud-zoom_lock_indicator-remind = Zoom locked
hud-zoom_lock_indicator-enable = Camera zoom locked
hud-zoom_lock_indicator-disable = Camera zoom unlocked
hud-collect = Collect
hud-pick_up = Pick up
hud-open = Open

View File

@ -2,6 +2,8 @@ hud-settings-general = General
hud-settings-none = None
hud-settings-press_behavior-toggle = Toggle
hud-settings-press_behavior-hold = Hold
hud-settings-autopress_behavior-toggle = Toggle
hud-settings-autopress_behavior-auto = Auto
hud-settings-help_window = Help Window
hud-settings-debug_info = Debug Info
hud-settings-show_hitboxes = Show hitboxes
@ -49,10 +51,12 @@ 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-zoom_lock_behavior = Camera zoom lock behavior
hud-settings-player_physics_behavior = Player physics (experimental)
hud-settings-stop_auto_walk_on_input = Stop auto walk on movement
hud-settings-auto_camera = Auto camera
hud-settings-bow_zoom = Zoom in when charging bow
hud-settings-zoom_lock = Camera zoom lock
hud-settings-reset_gameplay = Reset to Defaults
hud-settings-view_distance = View Distance
hud-settings-entity_view_distance = Entities View Distance

View File

@ -132,6 +132,8 @@ pub enum GameInput {
FreeLook,
#[strum(serialize = "gameinput-autowalk")]
AutoWalk,
#[strum(serialize = "gameinput-zoomlock")]
ZoomLock,
#[strum(serialize = "gameinput-cameraclamp")]
CameraClamp,
#[strum(serialize = "gameinput-cyclecamera")]

View File

@ -0,0 +1,86 @@
use serde::{Deserialize, Serialize};
use std::time::Duration;
/// Default initial alpha of a Notify
const NOTIF_START_ALPHA: f32 = 1.0;
/// Default time to live of a notify
const NOTIF_LIFETIME: f32 = 2.0;
/// Default fading time of a notify
const NOTIF_FADETIME: f32 = 1.5;
/// The reason this notification is being shown: the setting is being enabled or
/// disabled, or we are reminding the player of the current state.
#[derive(Clone, Copy, Debug, Deserialize, Serialize)]
pub enum NotificationReason {
Remind = 2,
Enable = 1,
#[serde(other)]
Disable = 0,
}
/// A temporal, fading message that a setting
/// or other state was changed (probably by direct player input)
#[derive(Default)]
pub struct ChangeNotification {
pub reason: Option<NotificationReason>,
pub alpha: f32,
lifetime: Duration,
fadetime: Duration,
initial_fadetime: Duration,
}
impl ChangeNotification {
pub fn new(
reason: Option<NotificationReason>,
alpha: f32,
lifetime: Duration,
fadetime: Duration,
) -> Result<Self, Duration> {
if fadetime.is_zero() {
Err(fadetime)
} else {
Ok(Self {
reason,
alpha,
lifetime,
fadetime,
initial_fadetime: fadetime,
})
}
}
pub fn from_reason(reason: NotificationReason) -> Self {
ChangeNotification::new(
Some(reason),
NOTIF_START_ALPHA,
Duration::from_secs_f32(NOTIF_LIFETIME),
Duration::from_secs_f32(NOTIF_FADETIME),
)
.unwrap()
}
pub fn from_state(state: bool) -> Self {
ChangeNotification::from_reason(match state {
true => NotificationReason::Enable,
false => NotificationReason::Disable,
})
}
pub fn update(&mut self, dt: Duration) {
if self.reason.is_some() {
// Timer before fade
if !self.lifetime.is_zero() {
self.lifetime = self.lifetime.saturating_sub(dt);
// Lifetime expired, start to fade
} else if !self.fadetime.is_zero() {
self.fadetime = self.fadetime.saturating_sub(dt);
// alpha as elapsed duration fraction, multiply with this for nice fade curve
self.alpha = self.fadetime.as_secs_f32() / self.initial_fadetime.as_secs_f32();
// Done fading
} else {
self.reason = None;
}
}
}
}

View File

@ -2,6 +2,7 @@ mod animation;
mod bag;
mod buffs;
mod buttons;
mod change_notification;
mod chat;
mod crafting;
mod diary;
@ -33,6 +34,7 @@ pub use settings_window::ScaleChange;
use bag::Bag;
use buffs::BuffsBar;
use buttons::Buttons;
use change_notification::{ChangeNotification, NotificationReason};
use chat::Chat;
use chrono::NaiveTime;
use crafting::Crafting;
@ -329,6 +331,10 @@ widget_ids! {
auto_walk_txt,
auto_walk_bg,
// Temporal (fading) camera zoom lock indicator
zoom_lock_txt,
zoom_lock_bg,
// Camera clamp indicator
camera_clamp_txt,
camera_clamp_bg,
@ -797,6 +803,16 @@ pub enum PressBehavior {
#[serde(other)]
Toggle = 0,
}
/// Similar to [PressBehavior], with different semantics for settings that
/// change state automatically. There is no [PressBehavior::update][update]
/// implementation because it doesn't apply to the use case; this is just a
/// sentinel.
#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
pub enum AutoPressBehavior {
Auto = 1,
#[serde(other)]
Toggle = 0,
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
pub struct ChatTab {
pub label: String,
@ -889,6 +905,7 @@ pub struct Show {
stats: bool,
free_look: bool,
auto_walk: bool,
zoom_lock: ChangeNotification,
camera_clamp: bool,
prompt_dialog: Option<PromptDialogSettings>,
location_markers: MapMarkers,
@ -1367,6 +1384,7 @@ impl Hud {
stats: false,
free_look: false,
auto_walk: false,
zoom_lock: ChangeNotification::default(),
camera_clamp: false,
prompt_dialog: None,
location_markers: MapMarkers::default(),
@ -3522,6 +3540,31 @@ impl Hud {
.set(self.ids.auto_walk_txt, ui_widgets);
}
// Camera zoom lock
self.show.zoom_lock.update(dt);
if let Some(zoom_lock) = self.show.zoom_lock.reason {
let zoom_lock_message = match zoom_lock {
NotificationReason::Remind => "hud-zoom_lock_indicator-remind",
NotificationReason::Enable => "hud-zoom_lock_indicator-enable",
NotificationReason::Disable => "hud-zoom_lock_indicator-disable",
};
Text::new(&i18n.get_msg(zoom_lock_message))
.color(TEXT_BG.alpha(self.show.zoom_lock.alpha))
.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.zoom_lock_bg, ui_widgets);
indicator_offset += 30.0;
Text::new(&i18n.get_msg(zoom_lock_message))
.color(TEXT_COLOR.alpha(self.show.zoom_lock.alpha))
.top_left_with_margins_on(self.ids.zoom_lock_bg, -1.0, -1.0)
.font_id(self.fonts.cyri.conrod_id)
.font_size(self.fonts.cyri.scale(20))
.set(self.ids.zoom_lock_txt, ui_widgets);
}
// Camera clamp indicator
if let Some(cameraclamp_key) = global_state
.settings
@ -4562,6 +4605,20 @@ impl Hud {
pub fn camera_clamp(&mut self, camera_clamp: bool) { self.show.camera_clamp = camera_clamp; }
/// Remind the player camera zoom is currently locked, for example if they
/// are trying to zoom.
pub fn zoom_lock_reminder(&mut self) {
if self.show.zoom_lock.reason.is_none() {
self.show.zoom_lock = ChangeNotification::from_reason(NotificationReason::Remind);
}
}
/// Start showing a temporary notification ([ChangeNotification]) that zoom
/// lock was toggled on/off.
pub fn zoom_lock_toggle(&mut self, state: bool) {
self.show.zoom_lock = ChangeNotification::from_state(state);
}
pub fn handle_outcome(
&mut self,
outcome: &Outcome,

View File

@ -1,7 +1,7 @@
use super::{RESET_BUTTONS_HEIGHT, RESET_BUTTONS_WIDTH};
use crate::{
hud::{img_ids::Imgs, PressBehavior, MENU_BG, TEXT_COLOR},
hud::{img_ids::Imgs, AutoPressBehavior, PressBehavior, MENU_BG, TEXT_COLOR},
session::settings_change::{Gameplay as GameplayChange, Gameplay::*},
ui::{fonts::Fonts, ImageSlider, ToggleButton},
GlobalState,
@ -44,12 +44,16 @@ widget_ids! {
auto_walk_behavior_list,
camera_clamp_behavior_text,
camera_clamp_behavior_list,
zoom_lock_behavior_text,
zoom_lock_behavior_list,
stop_auto_walk_on_input_button,
stop_auto_walk_on_input_label,
auto_camera_button,
auto_camera_label,
bow_zoom_button,
bow_zoom_label,
zoom_lock_button,
zoom_lock_label,
}
}
@ -528,6 +532,68 @@ impl<'a> Widget for Gameplay<'a> {
.color(TEXT_COLOR)
.set(state.ids.bow_zoom_label, ui);
let zoom_lock_label_list = [
self.localized_strings
.get_msg("hud-settings-autopress_behavior-toggle"),
self.localized_strings
.get_msg("hud-settings-autopress_behavior-auto"),
];
// Camera zoom lock behavior
Text::new(
&self
.localized_strings
.get_msg("hud-settings-zoom_lock_behavior"),
)
.down_from(state.ids.auto_walk_behavior_list, 10.0)
.font_size(self.fonts.cyri.scale(14))
.font_id(self.fonts.cyri.conrod_id)
.color(TEXT_COLOR)
.set(state.ids.zoom_lock_behavior_text, ui);
let zoom_lock_selected = self.global_state.settings.gameplay.zoom_lock_behavior as usize;
if let Some(clicked) = DropDownList::new(&zoom_lock_label_list, Some(zoom_lock_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.zoom_lock_behavior_text, 8.0)
.set(state.ids.zoom_lock_behavior_list, ui)
{
match clicked {
0 => events.push(ChangeZoomLockBehavior(AutoPressBehavior::Toggle)),
1 => events.push(ChangeZoomLockBehavior(AutoPressBehavior::Auto)),
_ => unreachable!(),
}
}
// Camera zoom lock toggle
let zoom_lock_toggle = ToggleButton::new(
self.global_state.settings.gameplay.zoom_lock,
self.imgs.checkbox,
self.imgs.checkbox_checked,
)
.w_h(18.0, 18.0)
.down_from(state.ids.bow_zoom_button, 8.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.zoom_lock_button, ui);
if self.global_state.settings.gameplay.zoom_lock != zoom_lock_toggle {
events.push(ChangeZoomLock(
!self.global_state.settings.gameplay.zoom_lock,
));
}
Text::new(&self.localized_strings.get_msg("hud-settings-zoom_lock"))
.right_from(state.ids.zoom_lock_button, 10.0)
.font_size(self.fonts.cyri.scale(14))
.font_id(self.fonts.cyri.conrod_id)
.graphics_for(state.ids.zoom_lock_button)
.color(TEXT_COLOR)
.set(state.ids.zoom_lock_label, ui);
// Reset the gameplay settings to the default settings
if Button::image(self.imgs.button)
.w_h(RESET_BUTTONS_WIDTH, RESET_BUTTONS_HEIGHT)

View File

@ -43,8 +43,8 @@ use crate::{
error::Error,
game_input::GameInput,
hud::{
DebugInfo, Event as HudEvent, Hud, HudCollectFailedReason, HudInfo, LootMessage,
PromptDialogSettings,
AutoPressBehavior, DebugInfo, Event as HudEvent, Hud, HudCollectFailedReason, HudInfo,
LootMessage, PromptDialogSettings,
},
key_state::KeyState,
menu::char_selection::CharSelectionState,
@ -61,6 +61,25 @@ use target::targets_under_cursor;
#[cfg(feature = "egui-ui")]
use voxygen_egui::EguiDebugInfo;
/** The zoom scroll delta that is considered an "intent"
to zoom, rather than the accidental zooming that Zoom Lock
is supposed to help.
This is used for both [AutoPressBehaviors::Toggle] and [AutoPressBehaviors::Auto].
This value should likely differ between trackpad scrolling
and various mouse wheels, but we just choose a reasonable
default.
All the mice I have can only scroll at |delta|=15 no matter
how fast, I guess the default should be less than that so
it gets seen. This could possibly be a user setting changed
only in a config file; it's too minor to put in the GUI.
If a player reports that their scroll wheel is apparently not
working, this value may be to blame (i.e. their intent to scroll
is not being detected at a low enough scroll speed).
*/
const ZOOM_LOCK_SCROLL_DELTA_INTENT: f32 = 14.0;
/// The action to perform after a tick
enum TickAction {
// Continue executing
@ -83,6 +102,7 @@ pub struct SessionState {
free_look: bool,
auto_walk: bool,
camera_clamp: bool,
zoom_lock: bool,
is_aiming: bool,
target_entity: Option<specs::Entity>,
selected_entity: Option<(specs::Entity, std::time::Instant)>,
@ -152,6 +172,7 @@ impl SessionState {
free_look: false,
auto_walk: false,
camera_clamp: false,
zoom_lock: false,
is_aiming: false,
target_entity: None,
selected_entity: None,
@ -171,6 +192,24 @@ impl SessionState {
self.key_state.auto_walk = false;
}
/// Possibly lock the camera zoom depending on the current behaviour, and
/// the current inputs if in the Auto state.
fn maybe_auto_zoom_lock(
&mut self,
zoom_lock_enabled: bool,
zoom_lock_behavior: AutoPressBehavior,
) {
if let AutoPressBehavior::Auto = zoom_lock_behavior {
// to add Analog detection, update the condition rhs with a check for
// MovementX/Y event from the last tick
self.zoom_lock = zoom_lock_enabled && self.should_auto_zoom_lock();
} else {
// it's intentional that the HUD notification is not shown in this case:
// refresh session from Settings HUD checkbox change
self.zoom_lock = zoom_lock_enabled;
}
}
/// Gets the entity that is the current viewpoint, and a bool if the client
/// is allowed to edit it's data.
fn viewpoint_entity(&self) -> (specs::Entity, bool) {
@ -406,6 +445,45 @@ impl SessionState {
/// Clean up the session (and the client attached to it) after a tick.
pub fn cleanup(&mut self) { self.client.borrow_mut().cleanup(); }
fn should_auto_zoom_lock(&self) -> bool {
let inputs_state = &self.inputs_state;
for input in inputs_state {
match input {
GameInput::Primary
| GameInput::Secondary
| GameInput::Block
| GameInput::MoveForward
| GameInput::MoveLeft
| GameInput::MoveRight
| GameInput::MoveBack
| GameInput::Jump
| GameInput::Roll
| GameInput::Sneak
| GameInput::AutoWalk
| GameInput::Climb
| GameInput::ClimbDown
| GameInput::SwimUp
| GameInput::SwimDown
| GameInput::SwapLoadout
| GameInput::ToggleWield
| GameInput::Slot1
| GameInput::Slot2
| GameInput::Slot3
| GameInput::Slot4
| GameInput::Slot5
| GameInput::Slot6
| GameInput::Slot7
| GameInput::Slot8
| GameInput::Slot9
| GameInput::Slot10
| GameInput::SpectateViewpoint
| GameInput::SpectateSpeedBoost => return true,
_ => (),
}
}
false
}
}
impl PlayState for SessionState {
@ -547,6 +625,11 @@ impl PlayState for SessionState {
drop(client);
self.maybe_auto_zoom_lock(
global_state.settings.gameplay.zoom_lock,
global_state.settings.gameplay.zoom_lock_behavior,
);
if presence == PresenceKind::Spectator {
let mut client = self.client.borrow_mut();
if client.spectate_position(cam_pos) {
@ -609,7 +692,6 @@ impl PlayState for SessionState {
continue;
}
}
match event {
Event::Close => {
return PlayStateResult::Shutdown;
@ -950,6 +1032,14 @@ impl PlayState for SessionState {
self.key_state.auto_walk =
self.auto_walk && !self.client.borrow().is_gliding();
},
GameInput::ZoomLock => {
if state {
global_state.settings.gameplay.zoom_lock ^= true;
self.hud
.zoom_lock_toggle(global_state.settings.gameplay.zoom_lock);
}
},
GameInput::CameraClamp => {
let hud = &mut self.hud;
global_state.settings.gameplay.camera_clamp_behavior.update(
@ -1032,6 +1122,13 @@ impl PlayState for SessionState {
message: screenshot_message,
}),
Event::Zoom(delta) if self.zoom_lock => {
// only fire this Hud event when player has "intent" to zoom
if delta.abs() > ZOOM_LOCK_SCROLL_DELTA_INTENT {
self.hud.zoom_lock_reminder();
}
},
// Pass all other events to the scene
event => {
self.scene.handle_input_event(event, &self.client.borrow());

View File

@ -3,8 +3,8 @@ use crate::{
controller::ControllerSettings,
game_input::GameInput,
hud::{
BarNumbers, BuffPosition, ChatTab, CrosshairType, Intro, PressBehavior, ScaleChange,
ShortcutNumbers, XpBar,
AutoPressBehavior, BarNumbers, BuffPosition, ChatTab, CrosshairType, Intro, PressBehavior,
ScaleChange, ShortcutNumbers, XpBar,
},
render::RenderMode,
settings::{
@ -68,9 +68,11 @@ pub enum Gameplay {
ChangeFreeLookBehavior(PressBehavior),
ChangeAutoWalkBehavior(PressBehavior),
ChangeCameraClampBehavior(PressBehavior),
ChangeZoomLockBehavior(AutoPressBehavior),
ChangeStopAutoWalkOnInput(bool),
ChangeAutoCamera(bool),
ChangeBowZoom(bool),
ChangeZoomLock(bool),
ResetGameplaySettings,
}
@ -386,6 +388,9 @@ impl SettingsChange {
Gameplay::ChangeCameraClampBehavior(behavior) => {
settings.gameplay.camera_clamp_behavior = behavior;
},
Gameplay::ChangeZoomLockBehavior(state) => {
settings.gameplay.zoom_lock_behavior = state;
},
Gameplay::ChangeStopAutoWalkOnInput(state) => {
settings.gameplay.stop_auto_walk_on_input = state;
},
@ -395,6 +400,9 @@ impl SettingsChange {
Gameplay::ChangeBowZoom(state) => {
settings.gameplay.bow_zoom = state;
},
Gameplay::ChangeZoomLock(state) => {
settings.gameplay.zoom_lock = state;
},
Gameplay::ResetGameplaySettings => {
// Reset Gameplay Settings
settings.gameplay = GameplaySettings::default();

View File

@ -170,6 +170,7 @@ impl ControlSettings {
GameInput::ToggleWield => Some(KeyMouse::Key(VirtualKeyCode::R)),
GameInput::FreeLook => Some(KeyMouse::Key(VirtualKeyCode::L)),
GameInput::AutoWalk => Some(KeyMouse::Key(VirtualKeyCode::Period)),
GameInput::ZoomLock => Some(KeyMouse::Key(VirtualKeyCode::Semicolon)),
GameInput::CameraClamp => Some(KeyMouse::Key(VirtualKeyCode::Apostrophe)),
GameInput::CycleCamera => Some(KeyMouse::Key(VirtualKeyCode::Key0)),
GameInput::Slot1 => Some(KeyMouse::Key(VirtualKeyCode::Key1)),

View File

@ -1,4 +1,4 @@
use crate::hud::PressBehavior;
use crate::hud::{AutoPressBehavior, PressBehavior};
use serde::{Deserialize, Serialize};
/// `GameplaySettings` contains sensitivity and gameplay options.
@ -14,9 +14,11 @@ pub struct GameplaySettings {
pub free_look_behavior: PressBehavior,
pub auto_walk_behavior: PressBehavior,
pub camera_clamp_behavior: PressBehavior,
pub zoom_lock_behavior: AutoPressBehavior,
pub stop_auto_walk_on_input: bool,
pub auto_camera: bool,
pub bow_zoom: bool,
pub zoom_lock: bool,
}
impl Default for GameplaySettings {
@ -31,9 +33,11 @@ impl Default for GameplaySettings {
free_look_behavior: PressBehavior::Toggle,
auto_walk_behavior: PressBehavior::Toggle,
camera_clamp_behavior: PressBehavior::Toggle,
zoom_lock_behavior: AutoPressBehavior::Auto,
stop_auto_walk_on_input: true,
auto_camera: false,
bow_zoom: true,
zoom_lock: false,
}
}
}