use crate::{ cash::CashInventory, control::CashHealPressed, hitpoints::Hitpoints, player::Player, protocol::{ClientToController, PlaySound}, }; use bevy::prelude::*; use bevy_replicon::prelude::{FromClient, SendMode, ServerTriggerExt, ToClients}; pub fn plugin(app: &mut App) { app.add_systems(FixedUpdate, on_heal_trigger); } #[derive(Debug, PartialEq, Eq)] struct HealAction { cost: i32, damage_healed: u32, } fn on_heal_trigger( mut commands: Commands, controllers: ClientToController, mut query: Query<(&mut Hitpoints, &mut CashInventory), With>, mut inputs: MessageReader>, ) { for press in inputs.read() { let controller = controllers.get_controller(press.client_id); let (mut hp, mut cash) = query.get_mut(controller).unwrap(); if hp.max() || cash.cash == 0 { return; } let action = heal(cash.cash, hp.get().1 - hp.get().0); hp.heal(action.damage_healed); cash.cash = cash.cash.saturating_sub(action.cost); //TODO: trigger ui cost animation commands.server_trigger(ToClients { mode: SendMode::Broadcast, message: PlaySound::CashHeal, }); } } fn heal(cash: i32, damage: u32) -> HealAction { let cost = (damage as f32 / 10. * 25.) as i32; if cash >= cost { HealAction { cost, damage_healed: damage, } } else { let damage_healed = (cash as f32 * 10. / 25.) as u32; HealAction { cost: cash, damage_healed, } } } #[cfg(test)] mod test { use super::*; #[test] fn test_heal() { assert_eq!( heal(100, 10), HealAction { cost: 25, damage_healed: 10 } ); assert_eq!( heal(100, 90), HealAction { cost: 100, damage_healed: 40 } ); } }