Merge branch 'snowram/projectile-offsets' into 'master'

Set projectile offsets in states instead of globally

See merge request veloren/veloren!2855
This commit is contained in:
Samuel Keiffer 2021-09-22 01:55:39 +00:00
commit 0b477ec9af
10 changed files with 63 additions and 25 deletions

View File

@ -66,6 +66,7 @@ pub enum ServerEvent {
Respawn(EcsEntity),
Shoot {
entity: EcsEntity,
pos: Pos,
dir: Dir,
body: comp::Body,
light: Option<comp::LightEmitter>,

View File

@ -1,5 +1,5 @@
use crate::{
comp::{Body, CharacterState, LightEmitter, ProjectileConstructor, StateUpdate},
comp::{Body, CharacterState, LightEmitter, Pos, ProjectileConstructor, StateUpdate},
event::ServerEvent,
states::{
behavior::{CharacterBehavior, JoinData},
@ -83,6 +83,9 @@ impl CharacterBehavior for Data {
);
// Shoots all projectiles simultaneously
for i in 0..self.static_data.num_projectiles {
// Gets offsets
let body_offsets = data.body.projectile_offsets(update.ori.look_vec());
let pos = Pos(data.pos.0 + body_offsets);
// Adds a slight spread to the projectiles. First projectile has no spread,
// and spread increases linearly with number of projectiles created.
let dir = Dir::from_unnormalized(data.inputs.look_dir.map(|x| {
@ -95,6 +98,7 @@ impl CharacterBehavior for Data {
// Tells server to create and shoot the projectile
update.server_events.push_front(ServerEvent::Shoot {
entity: data.entity,
pos,
dir,
body: self.static_data.projectile_body,
projectile: projectile.clone(),

View File

@ -1,7 +1,7 @@
use crate::{
comp::{
projectile::ProjectileConstructor, Body, CharacterState, EnergyChange, EnergySource,
LightEmitter, StateUpdate,
LightEmitter, Pos, StateUpdate,
},
event::ServerEvent,
states::{
@ -110,6 +110,9 @@ impl CharacterBehavior for Data {
let (crit_chance, crit_mult) =
get_crit_data(data, self.static_data.ability_info);
let buff_strength = get_buff_strength(data, self.static_data.ability_info);
// Gets offsets
let body_offsets = data.body.projectile_offsets(update.ori.look_vec());
let pos = Pos(data.pos.0 + body_offsets);
let projectile = arrow.create_projectile(
Some(*data.uid),
crit_chance,
@ -118,6 +121,7 @@ impl CharacterBehavior for Data {
);
update.server_events.push_front(ServerEvent::Shoot {
entity: data.entity,
pos,
dir: data.inputs.look_dir,
body: self.static_data.projectile_body,
projectile,

View File

@ -1,6 +1,6 @@
use crate::{
comp::{
Body, CharacterState, EnergyChange, EnergySource, LightEmitter, ProjectileConstructor,
Body, CharacterState, EnergyChange, EnergySource, LightEmitter, Pos, ProjectileConstructor,
StateUpdate,
},
event::ServerEvent,
@ -91,6 +91,9 @@ impl CharacterBehavior for Data {
let (crit_chance, crit_mult) =
get_crit_data(data, self.static_data.ability_info);
let buff_strength = get_buff_strength(data, self.static_data.ability_info);
// Gets offsets
let body_offsets = data.body.projectile_offsets(update.ori.look_vec());
let pos = Pos(data.pos.0 + body_offsets);
let projectile = self.static_data.projectile.create_projectile(
Some(*data.uid),
crit_chance,
@ -99,6 +102,7 @@ impl CharacterBehavior for Data {
);
update.server_events.push_front(ServerEvent::Shoot {
entity: data.entity,
pos,
dir: data.inputs.look_dir,
body: self.static_data.projectile_body,
projectile,

View File

@ -238,6 +238,32 @@ impl Body {
/// Returns how well a body can move backwards while strafing (0.0 = not at
/// all, 1.0 = same as forward)
pub fn reverse_move_factor(&self) -> f32 { 0.45 }
/// Returns the position where a projectile should be fired relative to this
/// body
pub fn projectile_offsets(&self, ori: Vec3<f32>) -> Vec3<f32> {
let body_offsets_z = match self {
Body::Golem(_) => self.height() * 0.4,
_ => self.eye_height(),
};
let dim = self.dimensions();
// The width (shoulder to shoulder) and length (nose to tail)
let (width, length) = (dim.x, dim.y);
let body_radius = if length > width {
// Dachshund-like
self.max_radius()
} else {
// Cyclops-like
self.min_radius()
};
Vec3::new(
body_radius * ori.x * 1.1,
body_radius * ori.y * 1.1,
body_offsets_z,
)
}
}
/// Handles updating `Components` to move player based on state of `JoinData`

View File

@ -173,6 +173,7 @@ pub fn handle_create_ship(
pub fn handle_shoot(
server: &mut Server,
entity: EcsEntity,
pos: Pos,
dir: Dir,
body: Body,
light: Option<LightEmitter>,
@ -182,11 +183,7 @@ pub fn handle_shoot(
) {
let state = server.state_mut();
let mut pos = if let Some(pos) = state.ecs().read_storage::<Pos>().get(entity) {
pos.0
} else {
return;
};
let pos = pos.0;
let vel = *dir * speed
+ state
@ -201,18 +198,6 @@ pub fn handle_shoot(
.write_resource::<Vec<Outcome>>()
.push(Outcome::ProjectileShot { pos, body, vel });
let eye_height =
state
.ecs()
.read_storage::<comp::Body>()
.get(entity)
.map_or(0.0, |b| match b {
comp::Body::Golem(_) => b.height() * 0.45,
_ => b.eye_height(),
});
pos.z += eye_height;
let mut builder = state.create_projectile(Pos(pos), Vel(vel), body, projectile);
if let Some(light) = light {
builder = builder.with(light)

View File

@ -71,13 +71,16 @@ impl Server {
ServerEvent::Bonk { pos, owner, target } => handle_bonk(self, pos, owner, target),
ServerEvent::Shoot {
entity,
pos,
dir,
body,
light,
projectile,
speed,
object,
} => handle_shoot(self, entity, dir, body, light, projectile, speed, object),
} => handle_shoot(
self, entity, pos, dir, body, light, projectile, speed, object,
),
ServerEvent::Shockwave {
properties,
pos,

View File

@ -1830,7 +1830,10 @@ impl<'a> AgentData<'a> {
+ charge_factor * c.static_data.scaled_projectile_speed;
aim_projectile(
projectile_speed,
Vec3::new(self.pos.0.x, self.pos.0.y, self.pos.0.z + eye_offset),
self.pos.0
+ self.body.map_or(Vec3::zero(), |body| {
body.projectile_offsets(self.ori.look_vec())
}),
Vec3::new(
tgt_data.pos.0.x,
tgt_data.pos.0.y,
@ -1842,7 +1845,10 @@ impl<'a> AgentData<'a> {
let projectile_speed = c.static_data.projectile_speed;
aim_projectile(
projectile_speed,
Vec3::new(self.pos.0.x, self.pos.0.y, self.pos.0.z + eye_offset),
self.pos.0
+ self.body.map_or(Vec3::zero(), |body| {
body.projectile_offsets(self.ori.look_vec())
}),
Vec3::new(
tgt_data.pos.0.x,
tgt_data.pos.0.y,
@ -1854,7 +1860,10 @@ impl<'a> AgentData<'a> {
let projectile_speed = c.static_data.projectile_speed;
aim_projectile(
projectile_speed,
Vec3::new(self.pos.0.x, self.pos.0.y, self.pos.0.z + eye_offset),
self.pos.0
+ self.body.map_or(Vec3::zero(), |body| {
body.projectile_offsets(self.ori.look_vec())
}),
Vec3::new(
tgt_data.pos.0.x,
tgt_data.pos.0.y,

View File

@ -115,6 +115,7 @@ impl<'a> System<'a> for Sys {
.expect("nonzero vector should normalize");
server_emitter.emit(ServerEvent::Shoot {
entity,
pos: *pos,
dir,
body: Body::Object(object::Body::for_firework(*reagent)),
light: Some(LightEmitter {

View File

@ -13,7 +13,7 @@ use common::{
use common_state::BlockChange;
use hashbrown::HashMap;
use specs::{join::Join, Entity, Read, Write};
use vek::Rgb;
use vek::{Rgb, Vec3};
pub fn dispatch_actions(system_data: &mut WiringData) {
let WiringData {
@ -113,6 +113,7 @@ fn dispatch_action_spawn_projectile(
// NOTE: constr in RFC is about Arrow projectile
server_emitter.emit(ServerEvent::Shoot {
entity,
pos: Pos(Vec3::zero()),
dir: Dir::forward(),
body: Body::Object(object::Body::Arrow),
projectile: constr.create_projectile(None, 0.0, 1.0, 1.0),