Improve first-person projectile aiming

This commit is contained in:
scott-c 2020-06-13 16:21:47 +08:00
parent b2dc95239d
commit 2686598f1f
7 changed files with 57 additions and 37 deletions

View File

@ -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

View File

@ -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,

View File

@ -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) }
} }

View File

@ -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 {

View File

@ -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,

View File

@ -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,
}; };

View File

@ -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()