use super::TriggerGun; use crate::{ GameState, billboards::Billboard, global_observer, heads_database::HeadsDatabase, hitpoints::Hit, loading_assets::GameAssets, physics_layers::GameLayer, sounds::PlaySound, tb_entities::EnemySpawn, utils::sprite_3d_animation::AnimationTimer, }; use avian3d::prelude::{ Collider, CollisionLayers, CollisionStarted, LayerMask, PhysicsLayer, Sensor, }; use bevy::{pbr::NotShadowCaster, prelude::*}; use bevy_polyline::prelude::*; use bevy_sprite3d::{Sprite3dBuilder, Sprite3dParams}; use std::f32::consts::PI; #[derive(Component)] struct GunProjectile { time: f32, owner_head: usize, } const MAX_SHOT_AGES: f32 = 1.; #[derive(Resource)] struct ShotAssets { image: Handle, layout: Handle, } pub fn plugin(app: &mut App) { app.add_systems(OnEnter(GameState::Playing), setup); app.add_systems( Update, (shot_collision, enemy_hit).run_if(in_state(GameState::Playing)), ); app.add_systems( FixedUpdate, (update, timeout).run_if(in_state(GameState::Playing)), ); global_observer!(app, on_trigger_gun); } fn setup(mut commands: Commands, assets: Res, mut sprite_params: Sprite3dParams) { let layout = TextureAtlasLayout::from_grid(UVec2::splat(256), 7, 6, None, None); let texture_atlas_layout = sprite_params.atlas_layouts.add(layout); commands.insert_resource(ShotAssets { image: assets.impact_atlas.clone(), layout: texture_atlas_layout, }); } fn enemy_hit( mut commands: Commands, mut collision_event_reader: EventReader, query_shot: Query<&GunProjectile>, query_npc: Query<&EnemySpawn>, heads_db: Res, ) { for CollisionStarted(e1, e2) in collision_event_reader.read() { if !query_shot.contains(*e1) && !query_shot.contains(*e2) { continue; } if !query_npc.contains(*e1) && !query_npc.contains(*e2) { continue; } let (enemy_entity, projectile) = if query_npc.contains(*e1) { (*e1, query_shot.get(*e2)) } else { (*e2, query_shot.get(*e1)) }; if let Ok(head) = projectile.map(|p| p.owner_head) { let damage = heads_db.head_stats(head).damage; commands.entity(enemy_entity).trigger(Hit { damage }); } } } fn on_trigger_gun( trigger: Trigger, mut commands: Commands, query_transform: Query<&Transform>, time: Res