unify explosion handling

This commit is contained in:
2025-06-09 22:02:17 +02:00
parent 69e112082a
commit 59c5b1f808
5 changed files with 51 additions and 73 deletions

View File

@@ -3,11 +3,12 @@ use crate::{
GameState, GameState,
billboards::Billboard, billboards::Billboard,
heads_database::HeadsDatabase, heads_database::HeadsDatabase,
hitpoints::Hit,
loading_assets::GameAssets, loading_assets::GameAssets,
physics_layers::GameLayer, physics_layers::GameLayer,
sounds::PlaySound, sounds::PlaySound,
utils::{global_observer, sprite_3d_animation::AnimationTimer, trail::Trail}, utils::{
explosions::Explosion, global_observer, sprite_3d_animation::AnimationTimer, trail::Trail,
},
}; };
use avian3d::prelude::*; use avian3d::prelude::*;
use bevy::{pbr::NotShadowCaster, prelude::*}; use bevy::{pbr::NotShadowCaster, prelude::*};
@@ -22,13 +23,6 @@ struct MissileProjectile {
damage: u32, damage: u32,
} }
#[derive(Event, Debug)]
struct Explosion {
position: Vec3,
radius: f32,
damage: u32,
}
#[derive(Resource)] #[derive(Resource)]
struct ShotAssets { struct ShotAssets {
image: Handle<Image>, image: Handle<Image>,
@@ -44,33 +38,6 @@ pub fn plugin(app: &mut App) {
); );
global_observer!(app, on_trigger_missile); global_observer!(app, on_trigger_missile);
global_observer!(app, on_explosion);
}
fn on_explosion(
explosion: Trigger<Explosion>,
mut commands: Commands,
spatial_query: SpatialQuery,
) {
let explosion = explosion.event();
let intersections = {
spatial_query.shape_intersections(
&Collider::sphere(explosion.radius),
explosion.position,
Quat::default(),
&SpatialQueryFilter::default().with_mask(LayerMask(
GameLayer::Npc.to_bits() | GameLayer::Player.to_bits(),
)),
)
};
for entity in intersections.iter() {
if let Ok(mut e) = commands.get_entity(*entity) {
e.trigger(Hit {
damage: explosion.damage,
});
}
}
} }
fn setup(mut commands: Commands, assets: Res<GameAssets>, mut sprite_params: Sprite3dParams) { fn setup(mut commands: Commands, assets: Res<GameAssets>, mut sprite_params: Sprite3dParams) {

View File

@@ -3,11 +3,13 @@ use crate::{
GameState, GameState,
billboards::Billboard, billboards::Billboard,
heads_database::HeadsDatabase, heads_database::HeadsDatabase,
hitpoints::Hit,
loading_assets::GameAssets, loading_assets::GameAssets,
physics_layers::GameLayer, physics_layers::GameLayer,
sounds::PlaySound, sounds::PlaySound,
utils::{auto_rotate::AutoRotation, global_observer, sprite_3d_animation::AnimationTimer}, utils::{
auto_rotate::AutoRotation, explosions::Explosion, global_observer,
sprite_3d_animation::AnimationTimer,
},
}; };
use avian3d::prelude::*; use avian3d::prelude::*;
use bevy::{pbr::NotShadowCaster, prelude::*}; use bevy::{pbr::NotShadowCaster, prelude::*};
@@ -21,13 +23,6 @@ struct ThrownProjectile {
damage: u32, damage: u32,
} }
#[derive(Event, Debug)]
struct Explosion {
position: Vec3,
radius: f32,
damage: u32,
}
#[derive(Resource)] #[derive(Resource)]
struct ShotAssets { struct ShotAssets {
image: Handle<Image>, image: Handle<Image>,
@@ -39,33 +34,6 @@ pub fn plugin(app: &mut App) {
app.add_systems(Update, shot_collision.run_if(in_state(GameState::Playing))); app.add_systems(Update, shot_collision.run_if(in_state(GameState::Playing)));
global_observer!(app, on_trigger_thrown); global_observer!(app, on_trigger_thrown);
global_observer!(app, on_explosion);
}
fn on_explosion(
explosion: Trigger<Explosion>,
mut commands: Commands,
spatial_query: SpatialQuery,
) {
let explosion = explosion.event();
let intersections = {
spatial_query.shape_intersections(
&Collider::sphere(explosion.radius),
explosion.position,
Quat::default(),
&SpatialQueryFilter::default().with_mask(LayerMask(
GameLayer::Npc.to_bits() | GameLayer::Player.to_bits(),
)),
)
};
for entity in intersections.iter() {
if let Ok(mut e) = commands.get_entity(*entity) {
e.trigger(Hit {
damage: explosion.damage,
});
}
}
} }
fn setup(mut commands: Commands, assets: Res<GameAssets>, mut sprite_params: Sprite3dParams) { fn setup(mut commands: Commands, assets: Res<GameAssets>, mut sprite_params: Sprite3dParams) {

View File

@@ -47,7 +47,7 @@ use loading_assets::AudioAssets;
use std::io::{Read, Write}; use std::io::{Read, Write};
use utils::{billboards, sprite_3d_animation, squish_animation, trail}; use utils::{billboards, sprite_3d_animation, squish_animation, trail};
use crate::utils::auto_rotate; use crate::utils::{auto_rotate, explosions};
#[derive(Resource, Reflect, Debug)] #[derive(Resource, Reflect, Debug)]
#[reflect(Resource)] #[reflect(Resource)]
@@ -173,6 +173,7 @@ fn main() {
app.add_plugins(auto_rotate::plugin); app.add_plugins(auto_rotate::plugin);
app.add_plugins(heal_effect::plugin); app.add_plugins(heal_effect::plugin);
app.add_plugins(tb_entities::plugin); app.add_plugins(tb_entities::plugin);
app.add_plugins(explosions::plugin);
app.init_state::<GameState>(); app.init_state::<GameState>();

41
src/utils/explosions.rs Normal file
View File

@@ -0,0 +1,41 @@
use avian3d::prelude::*;
use bevy::prelude::*;
use crate::{global_observer, hitpoints::Hit, physics_layers::GameLayer};
#[derive(Event, Debug)]
pub struct Explosion {
pub position: Vec3,
pub radius: f32,
pub damage: u32,
}
pub fn plugin(app: &mut App) {
global_observer!(app, on_explosion);
}
fn on_explosion(
explosion: Trigger<Explosion>,
mut commands: Commands,
spatial_query: SpatialQuery,
) {
let explosion = explosion.event();
let intersections = {
spatial_query.shape_intersections(
&Collider::sphere(explosion.radius),
explosion.position,
Quat::default(),
&SpatialQueryFilter::default().with_mask(LayerMask(
GameLayer::Npc.to_bits() | GameLayer::Player.to_bits(),
)),
)
};
for entity in intersections.iter() {
if let Ok(mut e) = commands.get_entity(*entity) {
e.trigger(Hit {
damage: explosion.damage,
});
}
}
}

View File

@@ -1,5 +1,6 @@
pub mod auto_rotate; pub mod auto_rotate;
pub mod billboards; pub mod billboards;
pub mod explosions;
pub mod observers; pub mod observers;
pub mod sprite_3d_animation; pub mod sprite_3d_animation;
pub mod squish_animation; pub mod squish_animation;