mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
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:
parent
9a025cfcc8
commit
83e4cdfe76
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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")]
|
||||
|
86
voxygen/src/hud/change_notification.rs
Normal file
86
voxygen/src/hud/change_notification.rs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -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,
|
||||
|
@ -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)
|
||||
|
@ -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());
|
||||
|
@ -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();
|
||||
|
@ -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)),
|
||||
|
@ -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,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user