use bevy::prelude::*;
#[derive(Event, Debug)]
struct DealDamage {
pub amount: i32,
}
#[derive(Event, Debug, Default)]
struct DamageReceived;
#[derive(Event, Debug, Default)]
struct ArmorBlockedDamage;
#[derive(Resource, Deref, DerefMut)]
struct DamageTimer(pub Timer);
impl Default for DamageTimer {
fn default() -> Self {
DamageTimer(Timer::from_seconds(1.0, TimerMode::Repeating))
}
}
fn deal_damage_over_time(
time: Res<Time>,
mut state: ResMut<DamageTimer>,
mut events: EventWriter<DealDamage>,
) {
if state.tick(time.delta()).finished() {
events.write(DealDamage { amount: 10 });
}
}
fn apply_armor_to_damage(
mut dmg_events: EventMutator<DealDamage>,
mut armor_events: EventWriter<ArmorBlockedDamage>,
) {
for event in dmg_events.read() {
event.amount -= 1;
if event.amount <= 0 {
armor_events.write(ArmorBlockedDamage);
}
}
}
fn apply_damage_to_health(
mut dmg_events: EventReader<DealDamage>,
mut rcvd_events: EventWriter<DamageReceived>,
) {
for event in dmg_events.read() {
info!("Applying {} damage", event.amount);
if event.amount > 0 {
rcvd_events.write_default();
}
}
}
fn play_damage_received_sound(mut dmg_events: EventReader<DamageReceived>) {
for _ in dmg_events.read() {
info!("Playing a sound.");
}
}
fn play_damage_received_particle_effect(mut dmg_events: EventReader<DamageReceived>) {
for _ in dmg_events.read() {
info!("Playing particle effect.");
}
}
fn main() {
App::new()
.add_plugins(DefaultPlugins)
.add_event::<DealDamage>()
.add_event::<ArmorBlockedDamage>()
.add_event::<DamageReceived>()
.init_resource::<DamageTimer>()
.add_systems(
Update,
(
deal_damage_over_time,
apply_armor_to_damage,
apply_damage_to_health,
)
.chain(),
)
.add_systems(
Update,
(
play_damage_received_sound,
play_damage_received_particle_effect,
),
)
.run();
}