mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Improve first-person projectile aiming
This commit is contained in:
parent
b2dc95239d
commit
2686598f1f
@ -33,6 +33,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
- Overhauled world colours
|
- Overhauled world colours
|
||||||
- Improved projectile physics
|
- Improved projectile physics
|
||||||
- Improved overhead aiming
|
- Improved overhead aiming
|
||||||
|
- Improved first person aiming
|
||||||
- Figure meshing no longer blocks the main thread.
|
- Figure meshing no longer blocks the main thread.
|
||||||
- Overhauled persistence layer including no longer storing serialized JSON items in the database
|
- Overhauled persistence layer including no longer storing serialized JSON items in the database
|
||||||
|
|
||||||
|
@ -140,7 +140,7 @@ impl Body {
|
|||||||
pub fn radius(&self) -> f32 {
|
pub fn radius(&self) -> f32 {
|
||||||
// TODO: Improve these values (some might be reliant on more info in inner type)
|
// TODO: Improve these values (some might be reliant on more info in inner type)
|
||||||
match self {
|
match self {
|
||||||
Body::Humanoid(_) => 0.35,
|
Body::Humanoid(body) => 0.35 * body.scale(),
|
||||||
Body::QuadrupedSmall(_) => 0.4,
|
Body::QuadrupedSmall(_) => 0.4,
|
||||||
Body::QuadrupedMedium(body) => match body.species {
|
Body::QuadrupedMedium(body) => match body.species {
|
||||||
quadruped_medium::Species::Grolgar => 1.9,
|
quadruped_medium::Species::Grolgar => 1.9,
|
||||||
@ -173,10 +173,10 @@ impl Body {
|
|||||||
pub fn height(&self) -> f32 {
|
pub fn height(&self) -> f32 {
|
||||||
match self {
|
match self {
|
||||||
Body::Humanoid(humanoid) => match humanoid.species {
|
Body::Humanoid(humanoid) => match humanoid.species {
|
||||||
humanoid::Species::Danari => 1.5,
|
humanoid::Species::Danari => 1.5 * humanoid.scale(),
|
||||||
humanoid::Species::Dwarf => 1.55,
|
humanoid::Species::Dwarf => 1.55 * humanoid.scale(),
|
||||||
humanoid::Species::Orc => 1.95,
|
humanoid::Species::Orc => 1.95 * humanoid.scale(),
|
||||||
_ => 1.8,
|
_ => 1.8 * humanoid.scale(),
|
||||||
},
|
},
|
||||||
Body::QuadrupedSmall(body) => match body.species {
|
Body::QuadrupedSmall(body) => match body.species {
|
||||||
quadruped_small::Species::Dodarock => 1.5,
|
quadruped_small::Species::Dodarock => 1.5,
|
||||||
|
@ -63,8 +63,33 @@ impl Body {
|
|||||||
.accessory
|
.accessory
|
||||||
.min(self.species.num_accessories(self.body_type) - 1);
|
.min(self.species.num_accessories(self.body_type) - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns a scale value relative to the average humanoid
|
||||||
|
pub fn scale(&self) -> f32 {
|
||||||
|
use BodyType::*;
|
||||||
|
use Species::*;
|
||||||
|
match (self.species, self.body_type) {
|
||||||
|
(Orc, Male) => 1.14,
|
||||||
|
(Orc, Female) => 1.02,
|
||||||
|
(Human, Male) => 1.02,
|
||||||
|
(Human, Female) => 0.96,
|
||||||
|
(Elf, Male) => 1.02,
|
||||||
|
(Elf, Female) => 0.96,
|
||||||
|
(Dwarf, Male) => 0.84,
|
||||||
|
(Dwarf, Female) => 0.78,
|
||||||
|
(Undead, Male) => 0.96,
|
||||||
|
(Undead, Female) => 0.9,
|
||||||
|
(Danari, Male) => 0.696,
|
||||||
|
(Danari, Female) => 0.696,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the eye height for this humanoid.
|
||||||
|
pub fn eye_height(&self) -> f32 { DEFAULT_HUMANOID_EYE_HEIGHT * self.scale() }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub const DEFAULT_HUMANOID_EYE_HEIGHT: f32 = 1.65;
|
||||||
|
|
||||||
impl From<Body> for super::Body {
|
impl From<Body> for super::Body {
|
||||||
fn from(body: Body) -> Self { super::Body::Humanoid(body) }
|
fn from(body: Body) -> Self { super::Body::Humanoid(body) }
|
||||||
}
|
}
|
||||||
|
@ -2,8 +2,8 @@ use crate::{sys, Server, StateExt};
|
|||||||
use common::{
|
use common::{
|
||||||
character::CharacterId,
|
character::CharacterId,
|
||||||
comp::{
|
comp::{
|
||||||
self, Agent, Alignment, Body, Gravity, Item, ItemDrop, LightEmitter, Loadout, Pos,
|
self, humanoid::DEFAULT_HUMANOID_EYE_HEIGHT, Agent, Alignment, Body, Gravity, Item,
|
||||||
Projectile, Scale, Stats, Vel, WaypointArea,
|
ItemDrop, LightEmitter, Loadout, Pos, Projectile, Scale, Stats, Vel, WaypointArea,
|
||||||
},
|
},
|
||||||
outcome::Outcome,
|
outcome::Outcome,
|
||||||
util::Dir,
|
util::Dir,
|
||||||
@ -105,8 +105,12 @@ pub fn handle_shoot(
|
|||||||
.write_resource::<Vec<Outcome>>()
|
.write_resource::<Vec<Outcome>>()
|
||||||
.push(Outcome::ProjectileShot { pos, body, vel });
|
.push(Outcome::ProjectileShot { pos, body, vel });
|
||||||
|
|
||||||
// TODO: Player height
|
let eye_height = match state.ecs().read_storage::<comp::Body>().get(entity) {
|
||||||
pos.z += 1.2;
|
Some(comp::Body::Humanoid(body)) => body.eye_height(),
|
||||||
|
_ => DEFAULT_HUMANOID_EYE_HEIGHT,
|
||||||
|
};
|
||||||
|
|
||||||
|
pos.z += eye_height;
|
||||||
|
|
||||||
let mut builder = state.create_projectile(Pos(pos), Vel(vel), body, projectile);
|
let mut builder = state.create_projectile(Pos(pos), Vel(vel), body, projectile);
|
||||||
if let Some(light) = light {
|
if let Some(light) = light {
|
||||||
|
@ -158,32 +158,12 @@ impl<'a> std::convert::TryFrom<&'a comp::Body> for SkeletonAttr {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SkeletonAttr {
|
|
||||||
pub fn calculate_scale(body: &Body) -> f32 {
|
|
||||||
use comp::humanoid::{BodyType::*, Species::*};
|
|
||||||
match (body.species, body.body_type) {
|
|
||||||
(Orc, Male) => 1.14,
|
|
||||||
(Orc, Female) => 1.02,
|
|
||||||
(Human, Male) => 1.02,
|
|
||||||
(Human, Female) => 0.96,
|
|
||||||
(Elf, Male) => 1.02,
|
|
||||||
(Elf, Female) => 0.96,
|
|
||||||
(Dwarf, Male) => 0.84,
|
|
||||||
(Dwarf, Female) => 0.78,
|
|
||||||
(Undead, Male) => 0.96,
|
|
||||||
(Undead, Female) => 0.9,
|
|
||||||
(Danari, Male) => 0.696,
|
|
||||||
(Danari, Female) => 0.696,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a> From<&'a Body> for SkeletonAttr {
|
impl<'a> From<&'a Body> for SkeletonAttr {
|
||||||
#[allow(clippy::match_single_binding)] // TODO: Pending review in #587
|
#[allow(clippy::match_single_binding)] // TODO: Pending review in #587
|
||||||
fn from(body: &'a Body) -> Self {
|
fn from(body: &'a Body) -> Self {
|
||||||
use comp::humanoid::{BodyType::*, Species::*};
|
use comp::humanoid::{BodyType::*, Species::*};
|
||||||
Self {
|
Self {
|
||||||
scaler: SkeletonAttr::calculate_scale(body),
|
scaler: body.scale(),
|
||||||
head_scale: match (body.species, body.body_type) {
|
head_scale: match (body.species, body.body_type) {
|
||||||
(Orc, Male) => 0.9,
|
(Orc, Male) => 0.9,
|
||||||
(Orc, Female) => 0.9,
|
(Orc, Female) => 0.9,
|
||||||
|
@ -23,10 +23,10 @@ use crate::{
|
|||||||
settings::Settings,
|
settings::Settings,
|
||||||
window::{AnalogGameInput, Event},
|
window::{AnalogGameInput, Event},
|
||||||
};
|
};
|
||||||
use anim::character::SkeletonAttr;
|
|
||||||
use client::Client;
|
use client::Client;
|
||||||
use common::{
|
use common::{
|
||||||
comp,
|
comp,
|
||||||
|
comp::humanoid::DEFAULT_HUMANOID_EYE_HEIGHT,
|
||||||
outcome::Outcome,
|
outcome::Outcome,
|
||||||
span,
|
span,
|
||||||
state::{DeltaTime, State},
|
state::{DeltaTime, State},
|
||||||
@ -456,10 +456,20 @@ impl Scene {
|
|||||||
.read_storage::<comp::Body>()
|
.read_storage::<comp::Body>()
|
||||||
.get(scene_data.player_entity)
|
.get(scene_data.player_entity)
|
||||||
{
|
{
|
||||||
Some(comp::Body::Humanoid(body)) => SkeletonAttr::calculate_scale(body),
|
Some(comp::Body::Humanoid(body)) => body.scale(),
|
||||||
_ => 1_f32,
|
_ => 1_f32,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let eye_height = match scene_data
|
||||||
|
.state
|
||||||
|
.ecs()
|
||||||
|
.read_storage::<comp::Body>()
|
||||||
|
.get(scene_data.player_entity)
|
||||||
|
{
|
||||||
|
Some(comp::Body::Humanoid(body)) => body.eye_height(),
|
||||||
|
_ => DEFAULT_HUMANOID_EYE_HEIGHT,
|
||||||
|
};
|
||||||
|
|
||||||
// Add the analog input to camera
|
// Add the analog input to camera
|
||||||
self.camera
|
self.camera
|
||||||
.rotate_by(Vec3::from([self.camera_input_state.x, 0.0, 0.0]));
|
.rotate_by(Vec3::from([self.camera_input_state.x, 0.0, 0.0]));
|
||||||
@ -475,13 +485,13 @@ impl Scene {
|
|||||||
if player_rolling {
|
if player_rolling {
|
||||||
player_scale * 0.8
|
player_scale * 0.8
|
||||||
} else if is_running && on_ground.unwrap_or(false) {
|
} else if is_running && on_ground.unwrap_or(false) {
|
||||||
player_scale * 1.65 + (scene_data.state.get_time() as f32 * 17.0).sin() * 0.05
|
eye_height + (scene_data.state.get_time() as f32 * 17.0).sin() * 0.05
|
||||||
} else {
|
} else {
|
||||||
player_scale * 1.65
|
eye_height
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
CameraMode::ThirdPerson if scene_data.is_aiming => player_scale * 2.2,
|
CameraMode::ThirdPerson if scene_data.is_aiming => player_scale * 2.2,
|
||||||
CameraMode::ThirdPerson => player_scale * 1.65,
|
CameraMode::ThirdPerson => eye_height,
|
||||||
CameraMode::Freefly => 0.0,
|
CameraMode::Freefly => 0.0,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@ use crate::{
|
|||||||
key_state::KeyState,
|
key_state::KeyState,
|
||||||
menu::char_selection::CharSelectionState,
|
menu::char_selection::CharSelectionState,
|
||||||
render::Renderer,
|
render::Renderer,
|
||||||
scene::{camera, Scene, SceneData},
|
scene::{camera, CameraMode, Scene, SceneData},
|
||||||
settings::{AudioOutput, ControlSettings, Settings},
|
settings::{AudioOutput, ControlSettings, Settings},
|
||||||
window::{AnalogGameInput, Event, GameInput},
|
window::{AnalogGameInput, Event, GameInput},
|
||||||
Direction, Error, GlobalState, PlayState, PlayStateResult,
|
Direction, Error, GlobalState, PlayState, PlayStateResult,
|
||||||
@ -248,7 +248,7 @@ impl PlayState for SessionState {
|
|||||||
|
|
||||||
(
|
(
|
||||||
is_aiming,
|
is_aiming,
|
||||||
if is_aiming {
|
if is_aiming && self.scene.camera().get_mode() == CameraMode::ThirdPerson {
|
||||||
Vec3::unit_z() * 0.05
|
Vec3::unit_z() * 0.05
|
||||||
} else {
|
} else {
|
||||||
Vec3::zero()
|
Vec3::zero()
|
||||||
|
Loading…
Reference in New Issue
Block a user