From 812dcbac7cab127fe6cfec1f70894436957fc0c0 Mon Sep 17 00:00:00 2001 From: extrawurst Date: Sun, 4 May 2025 14:19:56 +0200 Subject: [PATCH] medic healing ability --- assets/all.headsdb.ron | 2 +- assets/sfx/abilities/heal.ogg | Bin 9691 -> 6945 bytes src/abilities/healing.rs | 76 ++++++++++++++++++++++++++++++++++ src/abilities/mod.rs | 54 ++++++++++++++++++++---- src/heads/mod.rs | 33 +++++++++++++++ src/loading_assets.rs | 16 +++---- 6 files changed, 165 insertions(+), 16 deletions(-) create mode 100644 src/abilities/healing.rs diff --git a/assets/all.headsdb.ron b/assets/all.headsdb.ron index 4bfe812..680e084 100644 --- a/assets/all.headsdb.ron +++ b/assets/all.headsdb.ron @@ -3,7 +3,7 @@ /*01*/(key:"carnival knife thrower", range:60, ammo:5), /*02*/(key:"chicago gangster", ability:Gun, ammo:25, range:60), /*03*/(key:"commando", ability:Gun, aps:7.4, ammo:26, range:60, damage:12), - /*04*/(key:"field medic"), + /*04*/(key:"field medic", ability:Medic, aps:20), /*05*/(key:"geisha"), /*06*/(key:"goblin", ability:Arrow, aps:2, ammo:5, range:90, damage:50), /*07*/(key:"green grocer", range:60, ammo:10, damage:25), diff --git a/assets/sfx/abilities/heal.ogg b/assets/sfx/abilities/heal.ogg index 688ab3ba4049b72a9424e71ca3cd08aa91f4bb2d..ee32eb22dae4ade2b9744287dcc8246fafe18dd9 100644 GIT binary patch delta 3510 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 delta 6343 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 J-v{c>Mb7R^7d`+0 diff --git a/src/abilities/healing.rs b/src/abilities/healing.rs new file mode 100644 index 0000000..a2563a2 --- /dev/null +++ b/src/abilities/healing.rs @@ -0,0 +1,76 @@ +use bevy::prelude::*; + +use crate::{ + GameState, global_observer, heads::ActiveHeads, heads_database::HeadsDatabase, + hitpoints::Hitpoints, loading_assets::AudioAssets, +}; + +#[derive(Component)] +struct Healing(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, + mut cmds: Commands, + assets: Res, + 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::(); + } +} + +fn update( + mut query: Query<(&mut ActiveHeads, &mut Hitpoints), With>, + time: Res