Fix input drops/repetitions (#69)

This commit is contained in:
PROMETHIA-27
2025-10-07 15:31:17 -04:00
committed by GitHub
parent adaa9cab30
commit 8f24f4e03a
8 changed files with 286 additions and 110 deletions

View File

@@ -1,11 +1,11 @@
use super::TriggerMissile;
use crate::{
GameState,
abilities::BuildExplosionSprite,
abilities::{ExplodingProjectile, ExplodingProjectileSet},
heads_database::HeadsDatabase,
physics_layers::GameLayer,
protocol::{GltfSceneRoot, PlaySound},
utils::{commands::CommandExt, explosions::Explosion, global_observer, trail::Trail},
utils::{global_observer, trail::Trail},
};
use avian3d::prelude::*;
use bevy::prelude::*;
@@ -23,7 +23,10 @@ struct MissileProjectile {
}
pub fn plugin(app: &mut App) {
app.add_systems(Update, shot_collision.run_if(in_state(GameState::Playing)));
app.add_systems(
FixedUpdate,
shot_collision.in_set(ExplodingProjectileSet::Mark),
);
app.add_systems(
FixedUpdate,
(update, timeout).run_if(in_state(GameState::Playing)),
@@ -141,20 +144,14 @@ fn shot_collision(
continue;
};
commands.trigger(PlaySound::MissileExplosion);
commands.entity(shot_entity).despawn();
commands.trigger(Explosion {
commands.entity(shot_entity).insert(ExplodingProjectile {
sound: PlaySound::MissileExplosion,
damage,
position: shot_pos,
radius: 6.,
});
commands.trigger_server(BuildExplosionSprite {
pos: shot_pos,
pixels_per_meter: 16.,
time: 0.01,
radius: 6.0,
animation: true,
anim_pixels_per_meter: 16.0,
anim_time: 0.01,
});
}
}

View File

@@ -6,23 +6,27 @@ pub mod missile;
pub mod thrown;
use crate::{
GameState,
aim::AimTarget,
character::CharacterHierarchy,
global_observer,
heads::ActiveHeads,
heads_database::HeadsDatabase,
GameState, global_observer,
loading_assets::GameAssets,
physics_layers::GameLayer,
player::{Player, PlayerBodyMesh},
protocol::PlaySound,
utils::{billboards::Billboard, sprite_3d_animation::AnimationTimer},
};
#[cfg(feature = "server")]
use crate::{control::ControlState, head::ActiveHead};
use crate::{
aim::AimTarget,
character::CharacterHierarchy,
control::ControlState,
head::ActiveHead,
heads::ActiveHeads,
heads_database::HeadsDatabase,
player::{Player, PlayerBodyMesh},
utils::explosions::Explosion,
};
use bevy::{pbr::NotShadowCaster, prelude::*};
use bevy_sprite3d::{Sprite3dBuilder, Sprite3dParams};
pub use healing::Healing;
#[cfg(feature = "server")]
use healing::HealingStateChanged;
#[cfg(feature = "server")]
use lightyear::prelude::input::native::ActionState;
@@ -86,6 +90,7 @@ pub struct TriggerCurver(pub TriggerData);
#[derive(Resource, Default)]
pub struct TriggerStateRes {
#[cfg(feature = "server")]
next_trigger_timestamp: f32,
active: bool,
}
@@ -96,6 +101,25 @@ impl TriggerStateRes {
}
}
#[derive(Component)]
#[component(storage = "SparseSet")]
#[allow(dead_code)]
pub struct ExplodingProjectile {
sound: PlaySound,
damage: u32,
position: Vec3,
radius: f32,
animation: bool,
anim_pixels_per_meter: f32,
anim_time: f32,
}
#[derive(SystemSet, Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord)]
pub enum ExplodingProjectileSet {
Mark,
Explode,
}
pub fn plugin(app: &mut App) {
app.init_resource::<TriggerStateRes>();
@@ -106,20 +130,61 @@ pub fn plugin(app: &mut App) {
app.add_plugins(healing::plugin);
app.add_plugins(curver::plugin);
app.configure_sets(
FixedUpdate,
ExplodingProjectileSet::Explode
.after(ExplodingProjectileSet::Mark)
.run_if(in_state(GameState::Playing)),
);
app.add_systems(OnEnter(GameState::Playing), setup);
#[cfg(feature = "server")]
app.add_systems(
Update,
(update, update_heal_ability).run_if(in_state(GameState::Playing)),
FixedUpdate,
(on_trigger_state, update, update_heal_ability)
.chain()
.run_if(in_state(GameState::Playing)),
);
#[cfg(feature = "server")]
app.add_systems(
FixedUpdate,
on_trigger_state.run_if(in_state(GameState::Playing)),
explode_projectiles.in_set(ExplodingProjectileSet::Explode),
);
global_observer!(app, build_explosion_sprite);
}
#[cfg(feature = "server")]
fn explode_projectiles(mut commands: Commands, query: Query<(Entity, &ExplodingProjectile)>) {
for (shot_entity, projectile) in query.iter() {
if let Ok(mut entity) = commands.get_entity(shot_entity) {
entity.try_despawn();
} else {
continue;
}
commands.trigger(projectile.sound.clone());
commands.trigger(Explosion {
damage: projectile.damage,
position: projectile.position,
//TODO: should be around 1 grid in distance
radius: projectile.radius,
});
//TODO: support different impact animations
if projectile.animation {
use crate::utils::commands::CommandExt;
commands.trigger_server(BuildExplosionSprite {
pos: projectile.position,
pixels_per_meter: projectile.anim_pixels_per_meter,
time: projectile.anim_time,
});
}
}
}
#[cfg(feature = "server")]
fn on_trigger_state(
mut res: ResMut<TriggerStateRes>,
@@ -136,6 +201,7 @@ fn on_trigger_state(
}
}
#[cfg(feature = "server")]
fn update(
mut res: ResMut<TriggerStateRes>,
mut commands: Commands,
@@ -201,6 +267,7 @@ fn update(
}
}
#[cfg(feature = "server")]
fn update_heal_ability(
res: Res<TriggerStateRes>,
mut commands: Commands,

View File

@@ -1,13 +1,10 @@
use super::TriggerThrow;
use crate::{
GameState,
abilities::BuildExplosionSprite,
abilities::{ExplodingProjectile, ExplodingProjectileSet},
heads_database::HeadsDatabase,
physics_layers::GameLayer,
protocol::{GltfSceneRoot, PlaySound},
utils::{
auto_rotate::AutoRotation, commands::CommandExt, explosions::Explosion, global_observer,
},
utils::{auto_rotate::AutoRotation, global_observer},
};
use avian3d::prelude::*;
use bevy::prelude::*;
@@ -24,7 +21,10 @@ pub struct ThrownProjectile {
}
pub fn plugin(app: &mut App) {
app.add_systems(Update, shot_collision.run_if(in_state(GameState::Playing)));
app.add_systems(
FixedUpdate,
shot_collision.in_set(ExplodingProjectileSet::Mark),
);
global_observer!(app, on_trigger_thrown);
}
@@ -116,28 +116,14 @@ fn shot_collision(
continue;
};
if let Ok(mut entity) = commands.get_entity(shot_entity) {
entity.try_despawn();
} else {
continue;
}
commands.trigger(PlaySound::ThrowHit);
commands.trigger(Explosion {
commands.entity(shot_entity).insert(ExplodingProjectile {
sound: PlaySound::ThrowHit,
damage,
position: shot_pos,
//TODO: should be around 1 grid in distance
radius: 5.,
radius: 5.0,
animation,
anim_pixels_per_meter: 32.0,
anim_time: 0.02,
});
//TODO: support different impact animations
if animation {
commands.trigger_server(BuildExplosionSprite {
pos: shot_pos,
pixels_per_meter: 32.,
time: 0.02,
});
}
}
}