76 lines
2.0 KiB
Rust
76 lines
2.0 KiB
Rust
use crate::{
|
|
GameState, global_observer, heads::ActiveHeads, heads_database::HeadsDatabase,
|
|
hitpoints::Hitpoints, loading_assets::AudioAssets,
|
|
};
|
|
use bevy::prelude::*;
|
|
|
|
#[derive(Component)]
|
|
pub struct Healing(pub Entity);
|
|
|
|
#[derive(Event, Debug)]
|
|
pub enum HealingStateChanged {
|
|
Started,
|
|
Stopped,
|
|
}
|
|
|
|
pub fn plugin(app: &mut App) {
|
|
app.add_systems(Update, update.run_if(in_state(GameState::Playing)));
|
|
|
|
global_observer!(app, on_heal_start_stop);
|
|
}
|
|
|
|
fn on_heal_start_stop(
|
|
trigger: Trigger<HealingStateChanged>,
|
|
mut cmds: Commands,
|
|
assets: Res<AudioAssets>,
|
|
query: Query<&Healing>,
|
|
) {
|
|
if matches!(trigger.event(), HealingStateChanged::Started) {
|
|
let e = cmds
|
|
.spawn((
|
|
Name::new("sfx-heal"),
|
|
AudioPlayer::new(assets.healing.clone()),
|
|
PlaybackSettings {
|
|
mode: bevy::audio::PlaybackMode::Loop,
|
|
..Default::default()
|
|
},
|
|
))
|
|
.id();
|
|
cmds.entity(trigger.target())
|
|
.add_child(e)
|
|
.insert(Healing(e));
|
|
} else {
|
|
if let Ok(healing) = query.single() {
|
|
cmds.entity(healing.0).despawn();
|
|
}
|
|
cmds.entity(trigger.target()).remove::<Healing>();
|
|
}
|
|
}
|
|
|
|
fn update(
|
|
mut query: Query<(&mut ActiveHeads, &mut Hitpoints), With<Healing>>,
|
|
time: Res<Time>,
|
|
heads_db: Res<HeadsDatabase>,
|
|
) {
|
|
for (mut heads, mut hitpoints) in query.iter_mut() {
|
|
let Some(current) = heads.current() else {
|
|
continue;
|
|
};
|
|
|
|
let head = heads_db.head_stats(current.head);
|
|
|
|
if current.last_use + (1. / head.aps) > time.elapsed_secs() {
|
|
continue;
|
|
}
|
|
|
|
let medic_hp = hitpoints.get().0;
|
|
if medic_hp > 0 {
|
|
if let Some(health) = heads.medic_heal(2, time.elapsed_secs()) {
|
|
hitpoints.set_health(health);
|
|
} else {
|
|
continue;
|
|
}
|
|
}
|
|
}
|
|
}
|