mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Set projectile offsets in states instead of globally
This commit is contained in:
parent
576f2a6e9f
commit
9c2ce83430
@ -66,6 +66,7 @@ pub enum ServerEvent {
|
|||||||
Respawn(EcsEntity),
|
Respawn(EcsEntity),
|
||||||
Shoot {
|
Shoot {
|
||||||
entity: EcsEntity,
|
entity: EcsEntity,
|
||||||
|
pos: Pos,
|
||||||
dir: Dir,
|
dir: Dir,
|
||||||
body: comp::Body,
|
body: comp::Body,
|
||||||
light: Option<comp::LightEmitter>,
|
light: Option<comp::LightEmitter>,
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
comp::{Body, CharacterState, LightEmitter, ProjectileConstructor, StateUpdate},
|
comp::{Body, CharacterState, LightEmitter, Pos, ProjectileConstructor, StateUpdate},
|
||||||
event::ServerEvent,
|
event::ServerEvent,
|
||||||
states::{
|
states::{
|
||||||
behavior::{CharacterBehavior, JoinData},
|
behavior::{CharacterBehavior, JoinData},
|
||||||
@ -10,6 +10,7 @@ use crate::{
|
|||||||
use rand::{thread_rng, Rng};
|
use rand::{thread_rng, Rng};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
use vek::*;
|
||||||
|
|
||||||
/// Separated out to condense update portions of character state
|
/// Separated out to condense update portions of character state
|
||||||
#[derive(Clone, Copy, Debug, PartialEq, Serialize, Deserialize)]
|
#[derive(Clone, Copy, Debug, PartialEq, Serialize, Deserialize)]
|
||||||
@ -83,6 +84,9 @@ impl CharacterBehavior for Data {
|
|||||||
);
|
);
|
||||||
// Shoots all projectiles simultaneously
|
// Shoots all projectiles simultaneously
|
||||||
for i in 0..self.static_data.num_projectiles {
|
for i in 0..self.static_data.num_projectiles {
|
||||||
|
// Gets offsets
|
||||||
|
let body_offsets = projectile_offsets(data.body, update.ori.look_vec());
|
||||||
|
let pos = Pos(data.pos.0 + body_offsets);
|
||||||
// Adds a slight spread to the projectiles. First projectile has no spread,
|
// Adds a slight spread to the projectiles. First projectile has no spread,
|
||||||
// and spread increases linearly with number of projectiles created.
|
// and spread increases linearly with number of projectiles created.
|
||||||
let dir = Dir::from_unnormalized(data.inputs.look_dir.map(|x| {
|
let dir = Dir::from_unnormalized(data.inputs.look_dir.map(|x| {
|
||||||
@ -95,6 +99,7 @@ impl CharacterBehavior for Data {
|
|||||||
// Tells server to create and shoot the projectile
|
// Tells server to create and shoot the projectile
|
||||||
update.server_events.push_front(ServerEvent::Shoot {
|
update.server_events.push_front(ServerEvent::Shoot {
|
||||||
entity: data.entity,
|
entity: data.entity,
|
||||||
|
pos,
|
||||||
dir,
|
dir,
|
||||||
body: self.static_data.projectile_body,
|
body: self.static_data.projectile_body,
|
||||||
projectile: projectile.clone(),
|
projectile: projectile.clone(),
|
||||||
@ -141,3 +146,31 @@ impl CharacterBehavior for Data {
|
|||||||
fn reset_state(data: &Data, join: &JoinData, update: &mut StateUpdate) {
|
fn reset_state(data: &Data, join: &JoinData, update: &mut StateUpdate) {
|
||||||
handle_input(join, update, data.static_data.ability_info.input);
|
handle_input(join, update, data.static_data.ability_info.input);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn height_offset(body: &Body) -> f32 {
|
||||||
|
match body {
|
||||||
|
Body::Golem(_) => body.height() * 0.4,
|
||||||
|
_ => body.eye_height(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn projectile_offsets(body: &Body, ori: Vec3<f32>) -> Vec3<f32> {
|
||||||
|
let dim = body.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
|
||||||
|
body.max_radius()
|
||||||
|
} else {
|
||||||
|
// Cyclops-like
|
||||||
|
body.min_radius()
|
||||||
|
};
|
||||||
|
|
||||||
|
let body_offsets_z = height_offset(body);
|
||||||
|
|
||||||
|
Vec3::new(
|
||||||
|
body_radius * ori.x * 1.1,
|
||||||
|
body_radius * ori.y * 1.1,
|
||||||
|
body_offsets_z,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
comp::{
|
comp::{
|
||||||
projectile::ProjectileConstructor, Body, CharacterState, EnergyChange, EnergySource,
|
projectile::ProjectileConstructor, Body, CharacterState, EnergyChange, EnergySource,
|
||||||
LightEmitter, StateUpdate,
|
LightEmitter, Pos, StateUpdate,
|
||||||
},
|
},
|
||||||
event::ServerEvent,
|
event::ServerEvent,
|
||||||
states::{
|
states::{
|
||||||
@ -11,6 +11,7 @@ use crate::{
|
|||||||
};
|
};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
use vek::*;
|
||||||
|
|
||||||
/// Separated out to condense update portions of character state
|
/// Separated out to condense update portions of character state
|
||||||
#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)]
|
#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)]
|
||||||
@ -110,6 +111,9 @@ impl CharacterBehavior for Data {
|
|||||||
let (crit_chance, crit_mult) =
|
let (crit_chance, crit_mult) =
|
||||||
get_crit_data(data, self.static_data.ability_info);
|
get_crit_data(data, self.static_data.ability_info);
|
||||||
let buff_strength = get_buff_strength(data, self.static_data.ability_info);
|
let buff_strength = get_buff_strength(data, self.static_data.ability_info);
|
||||||
|
// Gets offsets
|
||||||
|
let body_offsets = projectile_offsets(data.body, update.ori.look_vec());
|
||||||
|
let pos = Pos(data.pos.0 + body_offsets);
|
||||||
let projectile = arrow.create_projectile(
|
let projectile = arrow.create_projectile(
|
||||||
Some(*data.uid),
|
Some(*data.uid),
|
||||||
crit_chance,
|
crit_chance,
|
||||||
@ -118,6 +122,7 @@ impl CharacterBehavior for Data {
|
|||||||
);
|
);
|
||||||
update.server_events.push_front(ServerEvent::Shoot {
|
update.server_events.push_front(ServerEvent::Shoot {
|
||||||
entity: data.entity,
|
entity: data.entity,
|
||||||
|
pos,
|
||||||
dir: data.inputs.look_dir,
|
dir: data.inputs.look_dir,
|
||||||
body: self.static_data.projectile_body,
|
body: self.static_data.projectile_body,
|
||||||
projectile,
|
projectile,
|
||||||
@ -187,3 +192,31 @@ impl CharacterBehavior for Data {
|
|||||||
update
|
update
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn height_offset(body: &Body) -> f32 {
|
||||||
|
match body {
|
||||||
|
Body::Golem(_) => body.height() * 0.4,
|
||||||
|
_ => body.eye_height(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn projectile_offsets(body: &Body, ori: Vec3<f32>) -> Vec3<f32> {
|
||||||
|
let dim = body.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
|
||||||
|
body.max_radius()
|
||||||
|
} else {
|
||||||
|
// Cyclops-like
|
||||||
|
body.min_radius()
|
||||||
|
};
|
||||||
|
|
||||||
|
let body_offsets_z = height_offset(body);
|
||||||
|
|
||||||
|
Vec3::new(
|
||||||
|
body_radius * ori.x * 1.1,
|
||||||
|
body_radius * ori.y * 1.1,
|
||||||
|
body_offsets_z,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
comp::{
|
comp::{
|
||||||
Body, CharacterState, EnergyChange, EnergySource, LightEmitter, ProjectileConstructor,
|
Body, CharacterState, EnergyChange, EnergySource, LightEmitter, Pos, ProjectileConstructor,
|
||||||
StateUpdate,
|
StateUpdate,
|
||||||
},
|
},
|
||||||
event::ServerEvent,
|
event::ServerEvent,
|
||||||
@ -11,6 +11,7 @@ use crate::{
|
|||||||
};
|
};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
use vek::*;
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, PartialEq, Serialize, Deserialize)]
|
#[derive(Clone, Copy, Debug, PartialEq, Serialize, Deserialize)]
|
||||||
/// Separated out to condense update portions of character state
|
/// Separated out to condense update portions of character state
|
||||||
@ -91,6 +92,9 @@ impl CharacterBehavior for Data {
|
|||||||
let (crit_chance, crit_mult) =
|
let (crit_chance, crit_mult) =
|
||||||
get_crit_data(data, self.static_data.ability_info);
|
get_crit_data(data, self.static_data.ability_info);
|
||||||
let buff_strength = get_buff_strength(data, self.static_data.ability_info);
|
let buff_strength = get_buff_strength(data, self.static_data.ability_info);
|
||||||
|
// Gets offsets
|
||||||
|
let body_offsets = projectile_offsets(data.body, update.ori.look_vec());
|
||||||
|
let pos = Pos(data.pos.0 + body_offsets);
|
||||||
let projectile = self.static_data.projectile.create_projectile(
|
let projectile = self.static_data.projectile.create_projectile(
|
||||||
Some(*data.uid),
|
Some(*data.uid),
|
||||||
crit_chance,
|
crit_chance,
|
||||||
@ -99,6 +103,7 @@ impl CharacterBehavior for Data {
|
|||||||
);
|
);
|
||||||
update.server_events.push_front(ServerEvent::Shoot {
|
update.server_events.push_front(ServerEvent::Shoot {
|
||||||
entity: data.entity,
|
entity: data.entity,
|
||||||
|
pos,
|
||||||
dir: data.inputs.look_dir,
|
dir: data.inputs.look_dir,
|
||||||
body: self.static_data.projectile_body,
|
body: self.static_data.projectile_body,
|
||||||
projectile,
|
projectile,
|
||||||
@ -164,3 +169,31 @@ impl CharacterBehavior for Data {
|
|||||||
update
|
update
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn height_offset(body: &Body) -> f32 {
|
||||||
|
match body {
|
||||||
|
Body::Golem(_) => body.height() * 0.4,
|
||||||
|
_ => body.eye_height(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn projectile_offsets(body: &Body, ori: Vec3<f32>) -> Vec3<f32> {
|
||||||
|
let dim = body.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
|
||||||
|
body.max_radius()
|
||||||
|
} else {
|
||||||
|
// Cyclops-like
|
||||||
|
body.min_radius()
|
||||||
|
};
|
||||||
|
|
||||||
|
let body_offsets_z = height_offset(body);
|
||||||
|
|
||||||
|
Vec3::new(
|
||||||
|
body_radius * ori.x * 1.1,
|
||||||
|
body_radius * ori.y * 1.1,
|
||||||
|
body_offsets_z,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
@ -173,6 +173,7 @@ pub fn handle_create_ship(
|
|||||||
pub fn handle_shoot(
|
pub fn handle_shoot(
|
||||||
server: &mut Server,
|
server: &mut Server,
|
||||||
entity: EcsEntity,
|
entity: EcsEntity,
|
||||||
|
pos: Pos,
|
||||||
dir: Dir,
|
dir: Dir,
|
||||||
body: Body,
|
body: Body,
|
||||||
light: Option<LightEmitter>,
|
light: Option<LightEmitter>,
|
||||||
@ -182,11 +183,7 @@ pub fn handle_shoot(
|
|||||||
) {
|
) {
|
||||||
let state = server.state_mut();
|
let state = server.state_mut();
|
||||||
|
|
||||||
let mut pos = if let Some(pos) = state.ecs().read_storage::<Pos>().get(entity) {
|
let pos = pos.0;
|
||||||
pos.0
|
|
||||||
} else {
|
|
||||||
return;
|
|
||||||
};
|
|
||||||
|
|
||||||
let vel = *dir * speed
|
let vel = *dir * speed
|
||||||
+ state
|
+ state
|
||||||
@ -201,18 +198,6 @@ pub fn handle_shoot(
|
|||||||
.write_resource::<Vec<Outcome>>()
|
.write_resource::<Vec<Outcome>>()
|
||||||
.push(Outcome::ProjectileShot { pos, body, vel });
|
.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);
|
let mut builder = state.create_projectile(Pos(pos), Vel(vel), body, projectile);
|
||||||
if let Some(light) = light {
|
if let Some(light) = light {
|
||||||
builder = builder.with(light)
|
builder = builder.with(light)
|
||||||
|
@ -71,13 +71,16 @@ impl Server {
|
|||||||
ServerEvent::Bonk { pos, owner, target } => handle_bonk(self, pos, owner, target),
|
ServerEvent::Bonk { pos, owner, target } => handle_bonk(self, pos, owner, target),
|
||||||
ServerEvent::Shoot {
|
ServerEvent::Shoot {
|
||||||
entity,
|
entity,
|
||||||
|
pos,
|
||||||
dir,
|
dir,
|
||||||
body,
|
body,
|
||||||
light,
|
light,
|
||||||
projectile,
|
projectile,
|
||||||
speed,
|
speed,
|
||||||
object,
|
object,
|
||||||
} => handle_shoot(self, entity, dir, body, light, projectile, speed, object),
|
} => handle_shoot(
|
||||||
|
self, entity, pos, dir, body, light, projectile, speed, object,
|
||||||
|
),
|
||||||
ServerEvent::Shockwave {
|
ServerEvent::Shockwave {
|
||||||
properties,
|
properties,
|
||||||
pos,
|
pos,
|
||||||
|
@ -28,7 +28,7 @@ use common::{
|
|||||||
path::TraversalConfig,
|
path::TraversalConfig,
|
||||||
resources::{DeltaTime, Time, TimeOfDay},
|
resources::{DeltaTime, Time, TimeOfDay},
|
||||||
rtsim::{Memory, MemoryItem, RtSimEntity, RtSimEvent},
|
rtsim::{Memory, MemoryItem, RtSimEntity, RtSimEvent},
|
||||||
states::{basic_beam, utils::StageSection},
|
states::{basic_beam, basic_ranged, charged_ranged, repeater_ranged, utils::StageSection},
|
||||||
terrain::{Block, TerrainGrid},
|
terrain::{Block, TerrainGrid},
|
||||||
time::DayPeriod,
|
time::DayPeriod,
|
||||||
trade::{TradeAction, TradePhase, TradeResult},
|
trade::{TradeAction, TradePhase, TradeResult},
|
||||||
@ -1830,7 +1830,10 @@ impl<'a> AgentData<'a> {
|
|||||||
+ charge_factor * c.static_data.scaled_projectile_speed;
|
+ charge_factor * c.static_data.scaled_projectile_speed;
|
||||||
aim_projectile(
|
aim_projectile(
|
||||||
projectile_speed,
|
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| {
|
||||||
|
charged_ranged::projectile_offsets(body, self.ori.look_vec())
|
||||||
|
}),
|
||||||
Vec3::new(
|
Vec3::new(
|
||||||
tgt_data.pos.0.x,
|
tgt_data.pos.0.x,
|
||||||
tgt_data.pos.0.y,
|
tgt_data.pos.0.y,
|
||||||
@ -1842,7 +1845,10 @@ impl<'a> AgentData<'a> {
|
|||||||
let projectile_speed = c.static_data.projectile_speed;
|
let projectile_speed = c.static_data.projectile_speed;
|
||||||
aim_projectile(
|
aim_projectile(
|
||||||
projectile_speed,
|
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| {
|
||||||
|
basic_ranged::projectile_offsets(body, self.ori.look_vec())
|
||||||
|
}),
|
||||||
Vec3::new(
|
Vec3::new(
|
||||||
tgt_data.pos.0.x,
|
tgt_data.pos.0.x,
|
||||||
tgt_data.pos.0.y,
|
tgt_data.pos.0.y,
|
||||||
@ -1854,7 +1860,10 @@ impl<'a> AgentData<'a> {
|
|||||||
let projectile_speed = c.static_data.projectile_speed;
|
let projectile_speed = c.static_data.projectile_speed;
|
||||||
aim_projectile(
|
aim_projectile(
|
||||||
projectile_speed,
|
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| {
|
||||||
|
repeater_ranged::projectile_offsets(body, self.ori.look_vec())
|
||||||
|
}),
|
||||||
Vec3::new(
|
Vec3::new(
|
||||||
tgt_data.pos.0.x,
|
tgt_data.pos.0.x,
|
||||||
tgt_data.pos.0.y,
|
tgt_data.pos.0.y,
|
||||||
|
@ -115,6 +115,7 @@ impl<'a> System<'a> for Sys {
|
|||||||
.expect("nonzero vector should normalize");
|
.expect("nonzero vector should normalize");
|
||||||
server_emitter.emit(ServerEvent::Shoot {
|
server_emitter.emit(ServerEvent::Shoot {
|
||||||
entity,
|
entity,
|
||||||
|
pos: *pos,
|
||||||
dir,
|
dir,
|
||||||
body: Body::Object(object::Body::for_firework(*reagent)),
|
body: Body::Object(object::Body::for_firework(*reagent)),
|
||||||
light: Some(LightEmitter {
|
light: Some(LightEmitter {
|
||||||
|
@ -13,7 +13,7 @@ use common::{
|
|||||||
use common_state::BlockChange;
|
use common_state::BlockChange;
|
||||||
use hashbrown::HashMap;
|
use hashbrown::HashMap;
|
||||||
use specs::{join::Join, Entity, Read, Write};
|
use specs::{join::Join, Entity, Read, Write};
|
||||||
use vek::Rgb;
|
use vek::{Rgb, Vec3};
|
||||||
|
|
||||||
pub fn dispatch_actions(system_data: &mut WiringData) {
|
pub fn dispatch_actions(system_data: &mut WiringData) {
|
||||||
let WiringData {
|
let WiringData {
|
||||||
@ -113,6 +113,7 @@ fn dispatch_action_spawn_projectile(
|
|||||||
// NOTE: constr in RFC is about Arrow projectile
|
// NOTE: constr in RFC is about Arrow projectile
|
||||||
server_emitter.emit(ServerEvent::Shoot {
|
server_emitter.emit(ServerEvent::Shoot {
|
||||||
entity,
|
entity,
|
||||||
|
pos: Pos(Vec3::zero()),
|
||||||
dir: Dir::forward(),
|
dir: Dir::forward(),
|
||||||
body: Body::Object(object::Body::Arrow),
|
body: Body::Object(object::Body::Arrow),
|
||||||
projectile: constr.create_projectile(None, 0.0, 1.0, 1.0),
|
projectile: constr.create_projectile(None, 0.0, 1.0, 1.0),
|
||||||
|
Loading…
Reference in New Issue
Block a user