use bevy::{ app::{Plugin, Update}, ecs::{ component::Component, entity::Entity, query::{With, Without}, system::{Commands, Query}, }, }; use guardian_core::{ components::*, dcs::text::TextMessage, srs::{voice::VoiceMessage, Radio, RadioInfo}, }; use crate::braa::Braa; pub struct TripwirePlugin; impl Plugin for TripwirePlugin { fn build(&self, app: &mut bevy::prelude::App) { app.add_systems(Update, tripwire); } } fn tripwire( mut commands: Commands, awacs: Query<(Entity, &Callsign, &Radio), (With, With, With)>, mut players: Query<(Entity, &Callsign, &Position, &RadioInfo, &mut Tripwire), With>, npc: Query<(&Id, &Position, &Heading, &Velocity), (Without, With)>, ) { // get the players radio frequencies // match the tuned frequency with one of the awacs' // broadcast message on that ferquency and as that awacs for (ent, awacs, radio) in awacs.iter() { for (p_ent, p_callsign, p_position, radioinfo, mut p_tripwire) in players.iter_mut() { // check if user is on the same frequency as awacs if !radioinfo .radios .iter() .any(|f| f.freq as u64 == radio.frequency && f.modulation == radio.modulation) { continue; } for (n_id, n_position, n_heading, n_velocity) in npc.iter() { if n_velocity.speed() < 10.0 { // ignore slow/on-ground units continue; } let distance = n_position.distance_to_nmi(p_position); if distance <= p_tripwire.range && !p_tripwire.reported.contains(n_id) { p_tripwire.reported.push(*n_id); let bra = Braa::new(p_position, n_position, n_heading); let message = format!("{}, {}, {}", p_callsign, awacs, bra); let voice_message = format!( "{} . . . {} . . . {}", p_callsign.to_voice(), awacs.to_voice(), bra.to_voice() ); // commands.spawn((Id::new(player_id.into()), TextMessage::new(message))); commands.entity(p_ent).insert(TextMessage::new(message)); commands .entity(ent) .insert(VoiceMessage::new(voice_message)); } else if distance > p_tripwire.range && p_tripwire.reported.contains(n_id) { p_tripwire.reported.retain(|b| b != n_id); } } } } } #[derive(Debug, Component)] pub struct Tripwire { range: f64, reported: Vec, } impl Tripwire { pub fn new(distance: i32) -> Self { Self { range: distance as f64, reported: vec![], } } }