92 lines
3.0 KiB
Rust
Executable File
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![],
|
|
}
|
|
}
|
|
}
|