fix(bow): Don't remove vel and use sticky component instead

This commit is contained in:
timokoesters 2019-10-02 21:28:35 +02:00
parent f1c4e7040a
commit 460a494e77
No known key found for this signature in database
GPG Key ID: CD80BE9AAEE78097
8 changed files with 61 additions and 32 deletions

View File

@ -23,7 +23,7 @@ pub use inputs::CanBuild;
pub use inventory::{item, Inventory, InventoryUpdate, Item};
pub use last::Last;
pub use location::Waypoint;
pub use phys::{ForceUpdate, Mass, Ori, PhysicsState, Pos, Scale, Vel};
pub use phys::{ForceUpdate, Mass, Ori, PhysicsState, Pos, Scale, Sticky, Vel};
pub use player::Player;
pub use projectile::Projectile;
pub use stats::{Equipment, Exp, HealthSource, Level, Stats};

View File

@ -43,6 +43,13 @@ impl Component for Mass {
type Storage = FlaggedStorage<Self, IDVStorage<Self>>;
}
#[derive(Copy, Clone, Default, Debug, PartialEq, Serialize, Deserialize)]
pub struct Sticky;
impl Component for Sticky {
type Storage = FlaggedStorage<Self, NullStorage<Self>>;
}
// PhysicsState
#[derive(Copy, Clone, Default, Debug, PartialEq, Serialize, Deserialize)]
pub struct PhysicsState {

View File

@ -31,6 +31,7 @@ sphynx::sum_type! {
Mounting(comp::Mounting),
Mass(comp::Mass),
Projectile(comp::Projectile),
Sticky(comp::Sticky),
}
}
// Automatically derive From<T> for EcsCompPhantom
@ -52,6 +53,7 @@ sphynx::sum_type! {
Mounting(PhantomData<comp::Mounting>),
Mass(PhantomData<comp::Mass>),
Projectile(PhantomData<comp::Projectile>),
Sticky(PhantomData<comp::Sticky>),
}
}
impl sphynx::CompPacket for EcsCompPacket {

View File

@ -132,6 +132,7 @@ impl State {
ecs.register_synced::<comp::Mounting>();
ecs.register_synced::<comp::MountState>();
ecs.register_synced::<comp::Mass>();
ecs.register_synced::<comp::Sticky>();
ecs.register_synced::<comp::Projectile>();
// Register components send from clients -> server

View File

@ -24,13 +24,13 @@ pub fn add_local_systems(dispatch_builder: &mut DispatcherBuilder) {
dispatch_builder.add(agent::Sys, AGENT_SYS, &[]);
dispatch_builder.add(controller::Sys, CONTROLLER_SYS, &[AGENT_SYS]);
dispatch_builder.add(movement::Sys, MOVEMENT_SYS, &[]);
dispatch_builder.add(projectile::Sys, PROJECTILE_SYS, &[CONTROLLER_SYS]);
dispatch_builder.add(combat::Sys, COMBAT_SYS, &[PROJECTILE_SYS]);
dispatch_builder.add(combat::Sys, COMBAT_SYS, &[CONTROLLER_SYS]);
dispatch_builder.add(stats::Sys, STATS_SYS, &[COMBAT_SYS]);
dispatch_builder.add(
phys::Sys,
PHYS_SYS,
&[CONTROLLER_SYS, MOVEMENT_SYS, COMBAT_SYS, STATS_SYS],
);
dispatch_builder.add(projectile::Sys, PROJECTILE_SYS, &[PHYS_SYS]);
dispatch_builder.add(cleanup::Sys, CLEANUP_SYS, &[PHYS_SYS]);
}

View File

@ -1,6 +1,6 @@
use {
crate::{
comp::{Body, Mass, Mounting, Ori, PhysicsState, Pos, Scale, Vel},
comp::{Body, Mass, Mounting, Ori, PhysicsState, Pos, Scale, Sticky, Vel},
event::{EventBus, LocalEvent},
state::DeltaTime,
terrain::{Block, TerrainGrid},
@ -47,6 +47,7 @@ impl<'a> System<'a> for Sys {
Read<'a, DeltaTime>,
Read<'a, EventBus<LocalEvent>>,
ReadStorage<'a, Scale>,
ReadStorage<'a, Sticky>,
ReadStorage<'a, Mass>,
ReadStorage<'a, Body>,
WriteStorage<'a, PhysicsState>,
@ -65,6 +66,7 @@ impl<'a> System<'a> for Sys {
dt,
event_bus,
scales,
stickies,
masses,
bodies,
mut physics_states,
@ -77,9 +79,10 @@ impl<'a> System<'a> for Sys {
let mut event_emitter = event_bus.emitter();
// Apply movement inputs
for (entity, scale, _b, mut pos, mut vel, _ori, _) in (
for (entity, scale, sticky, _b, mut pos, mut vel, _ori, _) in (
&entities,
scales.maybe(),
stickies.maybe(),
&bodies,
&mut positions,
&mut velocities,
@ -89,6 +92,11 @@ impl<'a> System<'a> for Sys {
.join()
{
let mut physics_state = physics_states.get(entity).cloned().unwrap_or_default();
if sticky.is_some() && (physics_state.on_wall.is_some() || physics_state.on_ground) {
continue;
}
let scale = scale.map(|s| s.0).unwrap_or(1.0);
// Basic collision with terrain
@ -338,6 +346,7 @@ impl<'a> System<'a> for Sys {
{
let scale = scale.map(|s| s.0).unwrap_or(1.0);
let mass = mass.map(|m| m.0).unwrap_or(scale);
for (other, pos_other, scale_other, mass_other, _, _) in (
&uids,
&positions,
@ -349,7 +358,12 @@ impl<'a> System<'a> for Sys {
.join()
{
let scale_other = scale_other.map(|s| s.0).unwrap_or(1.0);
let mass_other = mass_other.map(|m| m.0).unwrap_or(scale_other);
if mass_other == 0.0 {
continue;
}
let diff = Vec2::<f32>::from(pos.0 - pos_other.0);
let collision_dist = 0.95 * (scale + scale_other);

View File

@ -11,7 +11,7 @@ impl<'a> System<'a> for Sys {
Entities<'a>,
Read<'a, EventBus<ServerEvent>>,
ReadStorage<'a, PhysicsState>,
WriteStorage<'a, Vel>,
ReadStorage<'a, Vel>,
WriteStorage<'a, Ori>,
WriteStorage<'a, Projectile>,
);
@ -22,13 +22,15 @@ impl<'a> System<'a> for Sys {
entities,
server_bus,
physics_states,
mut velocities,
velocities,
mut orientations,
mut projectiles,
): Self::SystemData,
) {
let mut server_emitter = server_bus.emitter();
let mut todo = Vec::new();
// Attacks
for (entity, physics, ori, projectile) in (
&entities,
@ -38,28 +40,6 @@ impl<'a> System<'a> for Sys {
)
.join()
{
// Hit ground
if physics.on_ground {
for effect in projectile.hit_ground.drain(..) {
match effect {
projectile::Effect::Stick => {
velocities.remove(entity);
}
_ => {}
}
}
}
// Hit wall
if physics.on_wall.is_some() {
for effect in projectile.hit_wall.drain(..) {
match effect {
projectile::Effect::Stick => {
velocities.remove(entity);
}
_ => {}
}
}
}
// Hit entity
if let Some(other) = physics.touch_entity {
for effect in projectile.hit_entity.drain(..) {
@ -78,11 +58,34 @@ impl<'a> System<'a> for Sys {
_ => {}
}
}
todo.push(entity);
}
// Hit ground
else if physics.on_ground {
for effect in projectile.hit_ground.drain(..) {
match effect {
_ => {}
}
}
todo.push(entity);
}
// Hit wall
else if physics.on_wall.is_some() {
for effect in projectile.hit_wall.drain(..) {
match effect {
_ => {}
}
}
todo.push(entity);
} else {
if let Some(vel) = velocities.get(entity) {
ori.0 = vel.0.normalized();
}
}
}
if let Some(vel) = velocities.get(entity) {
ori.0 = vel.0.normalized();
}
for entity in todo {
projectiles.remove(entity);
}
}
}

View File

@ -211,8 +211,10 @@ impl Server {
.with(pos)
.with(vel)
.with(comp::Ori(vel.0.normalized()))
.with(comp::Mass(0.0))
.with(body)
.with(projectile)
.with(comp::Sticky)
}
pub fn create_player_character(