Files
guardian/src/tripwire.rs

92 lines
3.0 KiB
Rust
Executable File

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<Awacs>, With<Blue>, With<Radio>)>,
mut players: Query<(Entity, &Callsign, &Position, &RadioInfo, &mut Tripwire), With<Player>>,
npc: Query<(&Id, &Position, &Heading, &Velocity), (Without<Player>, With<Red>)>,
) {
// 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<Id>,
}
impl Tripwire {
pub fn new(distance: i32) -> Self {
Self {
range: distance as f64,
reported: vec![],
}
}
}