diff --git a/crates/shared/src/aim/mod.rs b/crates/shared/src/aim/mod.rs index 0da00ca..b012714 100644 --- a/crates/shared/src/aim/mod.rs +++ b/crates/shared/src/aim/mod.rs @@ -13,13 +13,14 @@ use crate::{ use avian3d::prelude::*; use bevy::prelude::*; use marker::MarkerEvent; +use serde::{Deserialize, Serialize}; use std::f32::consts::PI; -#[derive(Component, Reflect, Default, Deref)] +#[derive(Component, Reflect, Default, Deref, PartialEq, Serialize, Deserialize)] #[reflect(Component)] pub struct AimTarget(pub Option); -#[derive(Component, Reflect)] +#[derive(Component, Reflect, PartialEq, Serialize, Deserialize)] #[reflect(Component)] #[require(AimTarget)] pub struct AimState { @@ -39,6 +40,9 @@ impl Default for AimState { } pub fn plugin(app: &mut App) { + app.register_type::(); + app.register_type::(); + app.add_plugins(target_ui::plugin); app.add_plugins(marker::plugin); @@ -71,65 +75,66 @@ fn update_player_aim( mut commands: Commands, potential_targets: Query<(Entity, &Transform), With>, player_rot: Query<(&Transform, &GlobalTransform), With>, - mut player_aim: Query<(Entity, &AimState, &mut AimTarget), With>, + mut player_aim: Query<(Entity, &AimState, &mut AimTarget, &Children), With>, spatial_query: SpatialQuery, ) { - let Some((player, state, mut aim_target)) = player_aim.iter_mut().next() else { - return; - }; + for (player, state, mut aim_target, children) in player_aim.iter_mut() { + assert_eq!( + children.len(), + 1, + "expected player to have one direct child" + ); - let Some((player_pos, player_forward)) = player_rot - .iter() - .next() - .map(|(t, global)| (global.translation(), t.forward())) - else { - return; - }; + let (player_pos, player_forward) = player_rot + .get(*children.first().unwrap()) + .map(|(t, global)| (global.translation(), t.forward())) + .unwrap(); - let mut new_target = None; - let mut target_distance = f32::MAX; + let mut new_target = None; + let mut target_distance = f32::MAX; - for (e, t) in potential_targets.iter() { - if e == player { - continue; - } - - let delta = player_pos - t.translation; - - let distance = delta.length(); - - if distance > state.range { - continue; - } - - let angle = player_forward.angle_between(delta.normalize()); - - if angle < state.max_angle && distance < target_distance { - if !line_of_sight(&spatial_query, player_pos, delta, distance) { + for (e, t) in potential_targets.iter() { + if e == player { continue; } - new_target = Some(e); - target_distance = distance; - } - } + let delta = player_pos - t.translation; - if let Some(e) = &aim_target.0 - && commands.get_entity(*e).is_err() - { - aim_target.0 = None; - return; - } + let distance = delta.length(); - if new_target != aim_target.0 { - if state.spawn_marker { - if let Some(target) = new_target { - commands.trigger(MarkerEvent::Spawn(target)); - } else { - commands.trigger(MarkerEvent::Despawn); + if distance > state.range { + continue; + } + + let angle = player_forward.angle_between(delta.normalize()); + + if angle < state.max_angle && distance < target_distance { + if !line_of_sight(&spatial_query, player_pos, delta, distance) { + continue; + } + + new_target = Some(e); + target_distance = distance; } } - aim_target.0 = new_target; + + if let Some(e) = &aim_target.0 + && commands.get_entity(*e).is_err() + { + aim_target.0 = None; + return; + } + + if new_target != aim_target.0 { + if state.spawn_marker { + if let Some(target) = new_target { + commands.trigger(MarkerEvent::Spawn(target)); + } else { + commands.trigger(MarkerEvent::Despawn); + } + } + aim_target.0 = new_target; + } } } diff --git a/crates/shared/src/cutscene.rs b/crates/shared/src/cutscene.rs index f4c5672..2d8d1e0 100644 --- a/crates/shared/src/cutscene.rs +++ b/crates/shared/src/cutscene.rs @@ -6,8 +6,9 @@ use crate::{ }; use bevy::prelude::*; use bevy_trenchbroom::prelude::*; +use serde::{Deserialize, Serialize}; -#[derive(Event, Debug)] +#[derive(Clone, Debug, Event, Serialize, Deserialize)] pub struct StartCutscene(pub String); #[derive(Resource, Debug, Default)] diff --git a/crates/shared/src/head_drop.rs b/crates/shared/src/head_drop.rs index b3d4b1b..b929db4 100644 --- a/crates/shared/src/head_drop.rs +++ b/crates/shared/src/head_drop.rs @@ -1,6 +1,6 @@ use crate::{ GameState, billboards::Billboard, global_observer, heads_database::HeadsDatabase, - loading_assets::HeadDropAssets, physics_layers::GameLayer, player::Player, sounds::PlaySound, + physics_layers::GameLayer, player::Player, protocol::GltfSceneRoot, sounds::PlaySound, squish_animation::SquishAnimation, tb_entities::SecretHead, }; use avian3d::prelude::*; @@ -8,6 +8,8 @@ use bevy::{ ecs::{relationship::RelatedSpawner, spawn::SpawnWith}, prelude::*, }; +#[cfg(feature = "server")] +use lightyear::prelude::{NetworkTarget, Replicate}; use std::f32::consts::PI; #[derive(Event, Reflect)] @@ -77,9 +79,7 @@ fn spawn(mut commands: Commands, query: Query<(Entity, &GlobalTransform, &Secret fn on_head_drop( trigger: Trigger, mut commands: Commands, - assets: Res, heads_db: Res, - gltf_assets: Res>, time: Res