From a7602dfef4173a3dda50b5668980808207aa36f3 Mon Sep 17 00:00:00 2001 From: Woeful_Wolf <54476280+WoefulWolf@users.noreply.github.com> Date: Sun, 28 Jan 2024 16:08:28 +0200 Subject: [PATCH 1/7] Added basic ray_entities and closest_line_seg_line_seg methods --- voxygen/src/session/target.rs | 157 ++++++++++++++++++++++++++++++++++ 1 file changed, 157 insertions(+) diff --git a/voxygen/src/session/target.rs b/voxygen/src/session/target.rs index c61f5920b2..04921fe987 100644 --- a/voxygen/src/session/target.rs +++ b/voxygen/src/session/target.rs @@ -1,4 +1,7 @@ +use core::prelude::v1; + use specs::{Join, LendJoin, WorldExt}; +use tracing::{debug, info}; use vek::*; use client::{self, Client}; @@ -14,6 +17,8 @@ use common::{ }; use common_base::span; +use crate::scene::Scene; + #[derive(Clone, Copy, Debug)] pub struct Target { pub kind: T, @@ -238,3 +243,155 @@ pub(super) fn targets_under_cursor( terrain_target, ) } + +pub(super) fn ray_entities( + client: &Client, + start: Vec3, + end: Vec3, + cast_dist: f32, +) -> Option<(f32, Entity)> { + let player_entity = client.entity(); + let ecs = client.state().ecs(); + let positions = ecs.read_storage::(); + let colliders = ecs.read_storage::(); + + let mut nearby = ( + &ecs.entities(), + &positions, + &colliders, + ) + .join() + .filter(|(e, _, _)| *e != player_entity) + .filter_map(|(e, p, c)| { + let height = c.get_height(); + let radius = c.bounding_radius().max(height / 2.0); + // Move position up from the feet + let pos = Vec3::new(p.0.x, p.0.y, p.0.z + c.get_z_limits(1.0).0 + height/2.0); + // Distance squared from start to the entity + let dist_sqr = pos.distance_squared(start); + Some((e, pos, radius, dist_sqr, c)) + }) + // Roughly filter out entities farther than ray distance + .filter(|(_, _, _, d_sqr, c)| *d_sqr <= cast_dist.powi(2)) + .collect::>(); + // Sort by distance + nearby.sort_unstable_by(|a, b| a.3.partial_cmp(&b.3).unwrap()); + + let seg_ray = LineSegment3 { start, end }; + + let entity = nearby.iter().find_map(|(e, p, r, d_sqr, c)| { + let nearest = seg_ray.projected_point(*p); + + return match c { + comp::Collider::CapsulePrism { + p0, + p1, + radius, + z_min, + z_max, + } => { + if nearest.distance_squared(*p) < (r * 1.732).powi(2) { + // 1.732 = sqrt(3) + let entity_rotation = ecs + .read_storage::() + .get(*e) + .copied() + .unwrap_or_default(); + let entity_position = ecs.read_storage::().get(*e).copied().unwrap(); + let world_p0 = entity_position.0 + + (entity_rotation.to_quat() + * Vec3::new(p0.x, p0.y, z_min + c.get_height() / 2.0)); + let world_p1 = entity_position.0 + + (entity_rotation.to_quat() + * Vec3::new(p1.x, p1.y, z_min + c.get_height() / 2.0)); + + let (p_a, p_b) = if p0 != p1 { + let seg_capsule = LineSegment3 { + start: world_p0, + end: world_p1, + }; + closest_line_seg_line_seg( + seg_ray.start, + seg_ray.end, + seg_capsule.start, + seg_capsule.end, + ) + } else { + let nearest = seg_ray.projected_point(world_p0); + (nearest, world_p0) + }; + + let distance = p_a.xy().distance_squared(p_b.xy()); + + if distance < radius.powi(2) + && p_a.z >= entity_position.0.z + z_min + && p_a.z <= entity_position.0.z + z_max + { + return Some((p_a.distance(start), Entity(*e))); + } + } + None + }, + _ => { + if nearest.distance_squared(*p) < r.powi(2) { + return Some((nearest.distance(start), Entity(*e))); + } + None + }, + }; + }); + + return entity; +} + +// Get closest point between 2 line segments https://math.stackexchange.com/a/4289668 +fn closest_line_seg_line_seg( + p1: Vec3, + p2: Vec3, + p3: Vec3, + p4: Vec3, +) -> (Vec3, Vec3) { + let p1 = Vec3::new(p1.x as f64, p1.y as f64, p1.z as f64); + let p2 = Vec3::new(p2.x as f64, p2.y as f64, p2.z as f64); + let p3 = Vec3::new(p3.x as f64, p3.y as f64, p3.z as f64); + let p4 = Vec3::new(p4.x as f64, p4.y as f64, p4.z as f64); + + let P1 = p1; + let P2 = p3; + let V1 = p2 - p1; + let V2 = p4 - p3; + let V21 = P2 - P1; + + let v22 = V2.dot(V2); + let v11 = V1.dot(V1); + let v21 = V2.dot(V1); + let v21_1 = V21.dot(V1); + let v21_2 = V21.dot(V2); + + let denom = v21 * v21 - v22 * v11; + + let (s, t) = if denom == 0.0 { + let s = 0.0; + let t = (v11 * s - v21_1) / v21; + (s, t) + } else { + let s = (v21_2 * v21 - v22 * v21_1) / denom; + let t = (-v21_1 * v21 + v11 * v21_2) / denom; + (s, t) + }; + + let (s, t) = (s.clamp(0.0, 1.0), t.clamp(0.0, 1.0)); + + if s == 0.0 { + info!("p3: {}, p4: {}", p3, p4); + info!("s: {}, t: {}", s, t); + } + + let p_a = P1 + s * V1; + let p_b = P2 + t * V2; + + ( + Vec3::new(p_a.x as f32, p_a.y as f32, p_a.z as f32), + Vec3::new(p_b.x as f32, p_b.y as f32, p_b.z as f32), + ) +} From 6b6c5f18ec28f317e6cbd2ee5610a30be2717ccb Mon Sep 17 00:00:00 2001 From: Woeful_Wolf <54476280+WoefulWolf@users.noreply.github.com> Date: Sun, 28 Jan 2024 16:10:10 +0200 Subject: [PATCH 2/7] Added x and y camera offsets when aiming in third person --- voxygen/src/scene/mod.rs | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/voxygen/src/scene/mod.rs b/voxygen/src/scene/mod.rs index a813459769..ed31085b28 100644 --- a/voxygen/src/scene/mod.rs +++ b/voxygen/src/scene/mod.rs @@ -523,6 +523,7 @@ impl Scene { audio: &mut AudioFrontend, scene_data: &SceneData, client: &Client, + settings: &Settings, ) { span!(_guard, "maintain", "Scene::maintain"); // Get player position. @@ -629,15 +630,28 @@ impl Scene { viewpoint_eye_height } }, - CameraMode::ThirdPerson if scene_data.is_aiming => viewpoint_height * 1.16, + CameraMode::ThirdPerson if scene_data.is_aiming => { + viewpoint_height * 1.16 + settings.gameplay.aim_offset_y + }, CameraMode::ThirdPerson => viewpoint_eye_height, CameraMode::Freefly => 0.0, }; + + let right = match self.camera.get_mode() { + CameraMode::FirstPerson => 0.0, + CameraMode::ThirdPerson if scene_data.is_aiming => { + settings.gameplay.aim_offset_x + }, + CameraMode::ThirdPerson => 0.0, + CameraMode::Freefly => 0.0, + }; + // Alter camera position to match player. let tilt = self.camera.get_orientation().y; let dist = self.camera.get_distance(); Vec3::unit_z() * (up * viewpoint_scale - tilt.min(0.0).sin() * dist * 0.6) + + self.camera.right() * (right * viewpoint_scale) } else { self.figure_mgr .viewpoint_offset(scene_data, scene_data.viewpoint_entity) From 714dbc9c6f95228c596ebb92ba5d4efd9a3b5f89 Mon Sep 17 00:00:00 2001 From: Woeful_Wolf <54476280+WoefulWolf@users.noreply.github.com> Date: Sun, 28 Jan 2024 16:11:21 +0200 Subject: [PATCH 3/7] Added x and y aiming offsets to settings --- voxygen/src/hud/settings_window/gameplay.rs | 74 ++++++++++++++++++++- voxygen/src/session/settings_change.rs | 9 +++ voxygen/src/settings/gameplay.rs | 4 ++ 3 files changed, 86 insertions(+), 1 deletion(-) diff --git a/voxygen/src/hud/settings_window/gameplay.rs b/voxygen/src/hud/settings_window/gameplay.rs index d64d4614c6..6645e350a6 100644 --- a/voxygen/src/hud/settings_window/gameplay.rs +++ b/voxygen/src/hud/settings_window/gameplay.rs @@ -59,6 +59,12 @@ widget_ids! { bow_zoom_label, zoom_lock_button, zoom_lock_label, + aim_offset_x_slider, + aim_offset_x_label, + aim_offset_x_value, + aim_offset_y_slider, + aim_offset_y_label, + aim_offset_y_value, } } @@ -662,12 +668,78 @@ impl<'a> Widget for Gameplay<'a> { .color(TEXT_COLOR) .set(state.ids.zoom_lock_label, ui); + // Aim offset x + let display_aim_offset_x = self.global_state.settings.gameplay.aim_offset_x; + Text::new("Aim Offset X") + .down_from(state.ids.zoom_lock_behavior_list, 10.0) + .font_size(self.fonts.cyri.scale(14)) + .font_id(self.fonts.cyri.conrod_id) + .color(TEXT_COLOR) + .set(state.ids.aim_offset_x_label, ui); + + if let Some(new_val) = ImageSlider::continuous( + display_aim_offset_x, + -3.0, + 3.0, + self.imgs.slider_indicator, + self.imgs.slider, + ) + .w_h(550.0, 22.0) + .down_from(state.ids.aim_offset_x_label, 10.0) + .track_breadth(30.0) + .slider_length(10.0) + .pad_track((5.0, 5.0)) + .set(state.ids.aim_offset_x_slider, ui) + { + events.push(AdjustAimOffsetX(new_val)); + } + + Text::new(&format!("{:.2}", display_aim_offset_x)) + .right_from(state.ids.aim_offset_x_slider, 8.0) + .font_size(self.fonts.cyri.scale(14)) + .font_id(self.fonts.cyri.conrod_id) + .color(TEXT_COLOR) + .set(state.ids.aim_offset_x_value, ui); + + // Aim offset y + let display_aim_offset_y = self.global_state.settings.gameplay.aim_offset_y; + Text::new("Aim Offset Y") + .down_from(state.ids.aim_offset_x_slider, 10.0) + .font_size(self.fonts.cyri.scale(14)) + .font_id(self.fonts.cyri.conrod_id) + .color(TEXT_COLOR) + .set(state.ids.aim_offset_y_label, ui); + + if let Some(new_val) = ImageSlider::continuous( + display_aim_offset_y, + -3.0, + 3.0, + self.imgs.slider_indicator, + self.imgs.slider, + ) + .w_h(550.0, 22.0) + .down_from(state.ids.aim_offset_y_label, 10.0) + .track_breadth(30.0) + .slider_length(10.0) + .pad_track((5.0, 5.0)) + .set(state.ids.aim_offset_y_slider, ui) + { + events.push(AdjustAimOffsetY(new_val)); + } + + Text::new(&format!("{:.2}", display_aim_offset_y)) + .right_from(state.ids.aim_offset_y_slider, 8.0) + .font_size(self.fonts.cyri.scale(14)) + .font_id(self.fonts.cyri.conrod_id) + .color(TEXT_COLOR) + .set(state.ids.aim_offset_y_value, ui); + // Reset the gameplay settings to the default settings if Button::image(self.imgs.button) .w_h(RESET_BUTTONS_WIDTH, RESET_BUTTONS_HEIGHT) .hover_image(self.imgs.button_hover) .press_image(self.imgs.button_press) - .down_from(state.ids.zoom_lock_behavior_list, 12.0) + .down_from(state.ids.aim_offset_y_slider, 12.0) .label( &self .localized_strings diff --git a/voxygen/src/session/settings_change.rs b/voxygen/src/session/settings_change.rs index a4be0be0d8..0e7096230a 100644 --- a/voxygen/src/session/settings_change.rs +++ b/voxygen/src/session/settings_change.rs @@ -77,6 +77,9 @@ pub enum Gameplay { ChangeBowZoom(bool), ChangeZoomLock(bool), + AdjustAimOffsetX(f32), + AdjustAimOffsetY(f32), + ResetGameplaySettings, } #[derive(Clone)] @@ -427,6 +430,12 @@ impl SettingsChange { Gameplay::ChangeZoomLock(state) => { settings.gameplay.zoom_lock = state; }, + Gameplay::AdjustAimOffsetX(offset) => { + settings.gameplay.aim_offset_x = offset; + }, + Gameplay::AdjustAimOffsetY(offset) => { + settings.gameplay.aim_offset_y = offset; + }, Gameplay::ResetGameplaySettings => { // Reset Gameplay Settings settings.gameplay = GameplaySettings::default(); diff --git a/voxygen/src/settings/gameplay.rs b/voxygen/src/settings/gameplay.rs index ebb06d6627..839d50c260 100644 --- a/voxygen/src/settings/gameplay.rs +++ b/voxygen/src/settings/gameplay.rs @@ -21,6 +21,8 @@ pub struct GameplaySettings { pub auto_camera: bool, pub bow_zoom: bool, pub zoom_lock: bool, + pub aim_offset_x: f32, + pub aim_offset_y: f32, } impl Default for GameplaySettings { @@ -42,6 +44,8 @@ impl Default for GameplaySettings { auto_camera: false, bow_zoom: true, zoom_lock: false, + aim_offset_x: 1.0, + aim_offset_y: 0.0, } } } From ca022a1d1bcfd0b09787c2d8f3d51baca52f0d42 Mon Sep 17 00:00:00 2001 From: Woeful_Wolf <54476280+WoefulWolf@users.noreply.github.com> Date: Sun, 28 Jan 2024 16:12:25 +0200 Subject: [PATCH 4/7] Changed how look_dir is calculated when aiming, now ray casts entities and terrain to find target point --- voxygen/src/session/mod.rs | 72 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 70 insertions(+), 2 deletions(-) diff --git a/voxygen/src/session/mod.rs b/voxygen/src/session/mod.rs index 1ec6afb16e..24199f1c40 100644 --- a/voxygen/src/session/mod.rs +++ b/voxygen/src/session/mod.rs @@ -50,6 +50,7 @@ use crate::{ menu::char_selection::CharSelectionState, render::{Drawer, GlobalsBindGroup}, scene::{camera, CameraMode, DebugShapeId, Scene, SceneData}, + session::target::ray_entities, settings::Settings, window::{AnalogGameInput, Event}, Direction, GlobalState, PlayState, PlayStateResult, @@ -1349,8 +1350,74 @@ impl PlayState for SessionState { if !self.free_look { self.walk_forward_dir = self.scene.camera().forward_xy(); self.walk_right_dir = self.scene.camera().right_xy(); - self.inputs.look_dir = - Dir::from_unnormalized(cam_dir + aim_dir_offset).unwrap(); + + let dir = if is_aiming { + let client = self.client.borrow(); + // Shoot ray from camera forward direction and get the point it hits an + // entity or terrain + let ray_start = cam_pos + cam_dir * 2.0; + let entity_ray_end = ray_start + cam_dir * 500.0; + let terrain_ray_end = ray_start + cam_dir * 1000.0; + + let aim_point = match ray_entities( + &client, + ray_start, + entity_ray_end, + 500.0, + ) { + Some((dist, _)) => ray_start + cam_dir * dist, + None => { + let terrain_ray_distance = client + .state() + .terrain() + .ray(ray_start, terrain_ray_end) + .max_iter(1000) + .until(Block::is_solid) + .cast() + .0; + ray_start + cam_dir * terrain_ray_distance + }, + }; + + // Get player orientation + let ori = client + .state() + .read_storage::() + .get(player_entity) + .copied() + .unwrap(); + // Get player scale + let scale = client + .state() + .read_storage::() + .get(player_entity) + .copied() + .unwrap_or(comp::Scale(1.0)); + // Get player body offsets + let body = client + .state() + .read_storage::() + .get(player_entity) + .copied() + .unwrap(); + let body_offsets = body.projectile_offsets(ori.look_vec(), scale.0); + + // Get direction from player character to aim point + let player_pos = client + .state() + .read_storage::() + .get(player_entity) + .copied() + .unwrap(); + // self.scene.debug.add_shape(crate::scene::DebugShape::Line([aim_point, + // (player_pos.0 + Vec3 { x: 0.0, y: 0.0, z: 1000.0 })])); + drop(client); + aim_point - (player_pos.0 + body_offsets) + } else { + cam_dir + aim_dir_offset + }; + + self.inputs.look_dir = Dir::from_unnormalized(dir).unwrap(); } } self.inputs.strafing = matches!( @@ -2040,6 +2107,7 @@ impl PlayState for SessionState { &mut global_state.audio, &scene_data, &client, + &global_state.settings, ); // Process outcomes from client From a262521875e3cc23f995361af7bb740e8cde1c97 Mon Sep 17 00:00:00 2001 From: Woeful_Wolf <54476280+WoefulWolf@users.noreply.github.com> Date: Sun, 28 Jan 2024 16:34:52 +0200 Subject: [PATCH 5/7] Cleaned up some extra imports and debug code --- voxygen/src/session/mod.rs | 3 +-- voxygen/src/session/target.rs | 32 ++++++++++---------------------- 2 files changed, 11 insertions(+), 24 deletions(-) diff --git a/voxygen/src/session/mod.rs b/voxygen/src/session/mod.rs index 24199f1c40..c64f885aa2 100644 --- a/voxygen/src/session/mod.rs +++ b/voxygen/src/session/mod.rs @@ -1409,8 +1409,7 @@ impl PlayState for SessionState { .get(player_entity) .copied() .unwrap(); - // self.scene.debug.add_shape(crate::scene::DebugShape::Line([aim_point, - // (player_pos.0 + Vec3 { x: 0.0, y: 0.0, z: 1000.0 })])); + drop(client); aim_point - (player_pos.0 + body_offsets) } else { diff --git a/voxygen/src/session/target.rs b/voxygen/src/session/target.rs index 04921fe987..5256577840 100644 --- a/voxygen/src/session/target.rs +++ b/voxygen/src/session/target.rs @@ -1,7 +1,4 @@ -use core::prelude::v1; - use specs::{Join, LendJoin, WorldExt}; -use tracing::{debug, info}; use vek::*; use client::{self, Client}; @@ -17,8 +14,6 @@ use common::{ }; use common_base::span; -use crate::scene::Scene; - #[derive(Clone, Copy, Debug)] pub struct Target { pub kind: T, @@ -356,17 +351,15 @@ fn closest_line_seg_line_seg( let p3 = Vec3::new(p3.x as f64, p3.y as f64, p3.z as f64); let p4 = Vec3::new(p4.x as f64, p4.y as f64, p4.z as f64); - let P1 = p1; - let P2 = p3; - let V1 = p2 - p1; - let V2 = p4 - p3; - let V21 = P2 - P1; + let d1 = p2 - p1; + let d2 = p4 - p3; + let d21 = p3 - p1; - let v22 = V2.dot(V2); - let v11 = V1.dot(V1); - let v21 = V2.dot(V1); - let v21_1 = V21.dot(V1); - let v21_2 = V21.dot(V2); + let v22 = d2.dot(d2); + let v11 = d1.dot(d1); + let v21 = d2.dot(d1); + let v21_1 = d21.dot(d1); + let v21_2 = d21.dot(d2); let denom = v21 * v21 - v22 * v11; @@ -382,13 +375,8 @@ fn closest_line_seg_line_seg( let (s, t) = (s.clamp(0.0, 1.0), t.clamp(0.0, 1.0)); - if s == 0.0 { - info!("p3: {}, p4: {}", p3, p4); - info!("s: {}, t: {}", s, t); - } - - let p_a = P1 + s * V1; - let p_b = P2 + t * V2; + let p_a = p1 + s * d1; + let p_b = p3 + t * d2; ( Vec3::new(p_a.x as f32, p_a.y as f32, p_a.z as f32), From 29550f99628ca9117838bc86bf11a60251a12aef Mon Sep 17 00:00:00 2001 From: Woeful_Wolf <54476280+WoefulWolf@users.noreply.github.com> Date: Sun, 28 Jan 2024 16:51:00 +0200 Subject: [PATCH 6/7] code-quality edits --- voxygen/src/session/mod.rs | 34 +++++++++++++++------------------- voxygen/src/session/target.rs | 10 +++++----- 2 files changed, 20 insertions(+), 24 deletions(-) diff --git a/voxygen/src/session/mod.rs b/voxygen/src/session/mod.rs index c64f885aa2..37561f0f65 100644 --- a/voxygen/src/session/mod.rs +++ b/voxygen/src/session/mod.rs @@ -1359,25 +1359,21 @@ impl PlayState for SessionState { let entity_ray_end = ray_start + cam_dir * 500.0; let terrain_ray_end = ray_start + cam_dir * 1000.0; - let aim_point = match ray_entities( - &client, - ray_start, - entity_ray_end, - 500.0, - ) { - Some((dist, _)) => ray_start + cam_dir * dist, - None => { - let terrain_ray_distance = client - .state() - .terrain() - .ray(ray_start, terrain_ray_end) - .max_iter(1000) - .until(Block::is_solid) - .cast() - .0; - ray_start + cam_dir * terrain_ray_distance - }, - }; + let aim_point = + match ray_entities(&client, ray_start, entity_ray_end, 500.0) { + Some((dist, _)) => ray_start + cam_dir * dist, + None => { + let terrain_ray_distance = client + .state() + .terrain() + .ray(ray_start, terrain_ray_end) + .max_iter(1000) + .until(Block::is_solid) + .cast() + .0; + ray_start + cam_dir * terrain_ray_distance + }, + }; // Get player orientation let ori = client diff --git a/voxygen/src/session/target.rs b/voxygen/src/session/target.rs index 5256577840..70fd3c015a 100644 --- a/voxygen/src/session/target.rs +++ b/voxygen/src/session/target.rs @@ -257,24 +257,24 @@ pub(super) fn ray_entities( ) .join() .filter(|(e, _, _)| *e != player_entity) - .filter_map(|(e, p, c)| { + .map(|(e, p, c)| { let height = c.get_height(); let radius = c.bounding_radius().max(height / 2.0); // Move position up from the feet let pos = Vec3::new(p.0.x, p.0.y, p.0.z + c.get_z_limits(1.0).0 + height/2.0); // Distance squared from start to the entity let dist_sqr = pos.distance_squared(start); - Some((e, pos, radius, dist_sqr, c)) + (e, pos, radius, dist_sqr, c) }) // Roughly filter out entities farther than ray distance - .filter(|(_, _, _, d_sqr, c)| *d_sqr <= cast_dist.powi(2)) + .filter(|(_, _, _, d_sqr, _)| *d_sqr <= cast_dist.powi(2)) .collect::>(); // Sort by distance nearby.sort_unstable_by(|a, b| a.3.partial_cmp(&b.3).unwrap()); let seg_ray = LineSegment3 { start, end }; - let entity = nearby.iter().find_map(|(e, p, r, d_sqr, c)| { + let entity = nearby.iter().find_map(|(e, p, r, _, c)| { let nearest = seg_ray.projected_point(*p); return match c { @@ -336,7 +336,7 @@ pub(super) fn ray_entities( }; }); - return entity; + entity } // Get closest point between 2 line segments https://math.stackexchange.com/a/4289668 From 9af75e1fc920492c6bed14bcba87a6e3b192253e Mon Sep 17 00:00:00 2001 From: Woeful_Wolf <54476280+WoefulWolf@users.noreply.github.com> Date: Sun, 28 Jan 2024 18:00:56 +0200 Subject: [PATCH 7/7] Settings labels use i18n --- assets/voxygen/i18n/en/hud/settings.ftl | 4 +++- voxygen/src/hud/settings_window/gameplay.rs | 4 ++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/assets/voxygen/i18n/en/hud/settings.ftl b/assets/voxygen/i18n/en/hud/settings.ftl index b61b457e7d..2a3d61bca0 100644 --- a/assets/voxygen/i18n/en/hud/settings.ftl +++ b/assets/voxygen/i18n/en/hud/settings.ftl @@ -57,6 +57,8 @@ hud-settings-walking_speed_behavior = Walking speed behavior hud-settings-walking_speed = Walking speed hud-settings-camera_clamp_behavior = Camera clamp behavior hud-settings-zoom_lock_behavior = Camera zoom lock behavior +hud-settings-aim_offset_x = Horizontal Aim Offset +hud-settings-aim_offset_y = Vertical Aim Offset 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 @@ -158,4 +160,4 @@ hud-settings-group_only = Group only hud-settings-reset_chat = Reset to Defaults hud-settings-third_party_integrations = Third-party Integrations hud-settings-enable_discord_integration = Enable Discord Integration -hud-settings-subtitles = Subtitles +hud-settings-subtitles = Subtitles \ No newline at end of file diff --git a/voxygen/src/hud/settings_window/gameplay.rs b/voxygen/src/hud/settings_window/gameplay.rs index 6645e350a6..bd3d641af0 100644 --- a/voxygen/src/hud/settings_window/gameplay.rs +++ b/voxygen/src/hud/settings_window/gameplay.rs @@ -670,7 +670,7 @@ impl<'a> Widget for Gameplay<'a> { // Aim offset x let display_aim_offset_x = self.global_state.settings.gameplay.aim_offset_x; - Text::new("Aim Offset X") + Text::new(&self.localized_strings.get_msg("hud-settings-aim_offset_x")) .down_from(state.ids.zoom_lock_behavior_list, 10.0) .font_size(self.fonts.cyri.scale(14)) .font_id(self.fonts.cyri.conrod_id) @@ -703,7 +703,7 @@ impl<'a> Widget for Gameplay<'a> { // Aim offset y let display_aim_offset_y = self.global_state.settings.gameplay.aim_offset_y; - Text::new("Aim Offset Y") + Text::new(&self.localized_strings.get_msg("hud-settings-aim_offset_y")) .down_from(state.ids.aim_offset_x_slider, 10.0) .font_size(self.fonts.cyri.scale(14)) .font_id(self.fonts.cyri.conrod_id)