use bevy::prelude::*;
#[derive(Message, Debug)]
struct DealDamage {
pub amount: i32,
}
#[derive(Message, Debug, Default)]
struct DamageReceived;
#[derive(Message, 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 deal_damage_writer: MessageWriter<DealDamage>,
) {
if state.tick(time.delta()).is_finished() {
deal_damage_writer.write(DealDamage { amount: 10 });
}
}
fn apply_armor_to_damage(
mut dmg_messages: MessageMutator<DealDamage>,
mut armor_messages: MessageWriter<ArmorBlockedDamage>,
) {
for message in dmg_messages.read() {
message.amount -= 1;
if message.amount <= 0 {
armor_messages.write(ArmorBlockedDamage);
}
}
}
fn apply_damage_to_health(
mut deal_damage_reader: MessageReader<DealDamage>,
mut damaged_received_writer: MessageWriter<DamageReceived>,
) {
for deal_damage in deal_damage_reader.read() {
info!("Applying {} damage", deal_damage.amount);
if deal_damage.amount > 0 {
damaged_received_writer.write_default();
}
}
}
fn play_damage_received_sound(mut damage_received_reader: MessageReader<DamageReceived>) {
for _ in damage_received_reader.read() {
info!("Playing a sound.");
}
}
fn play_damage_received_particle_effect(mut damage_received_reader: MessageReader<DamageReceived>) {
for _ in damage_received_reader.read() {
info!("Playing particle effect.");
}
}
fn main() {
App::new()
.add_plugins(DefaultPlugins)
.add_message::<DealDamage>()
.add_message::<ArmorBlockedDamage>()
.add_message::<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();
}