use bevy::{ecs::event::SetEntityEventTarget, prelude::*};
use bevy_diesel::submit_propagation_for;
#[derive(Event, Clone, Reflect)]
pub struct Hit {
pub attacker: Entity,
pub defender: Entity,
pub amount: f32,
}
#[derive(EntityEvent, Clone, Reflect)]
pub struct HitAA {
#[event_target]
pub target: Entity,
pub base: Hit,
}
impl SetEntityEventTarget for HitAA {
fn set_event_target(&mut self, target: Entity) { self.target = target; }
}
#[derive(EntityEvent, Clone, Reflect)]
pub struct HitAD {
#[event_target]
pub target: Entity,
pub base: Hit,
}
impl SetEntityEventTarget for HitAD {
fn set_event_target(&mut self, target: Entity) { self.target = target; }
}
#[derive(EntityEvent, Clone, Reflect)]
pub struct HitDA {
#[event_target]
pub target: Entity,
pub base: Hit,
}
impl SetEntityEventTarget for HitDA {
fn set_event_target(&mut self, target: Entity) { self.target = target; }
}
#[derive(EntityEvent, Clone, Reflect)]
pub struct HitDD {
#[event_target]
pub target: Entity,
pub base: Hit,
}
impl SetEntityEventTarget for HitDD {
fn set_event_target(&mut self, target: Entity) { self.target = target; }
}
submit_propagation_for!(HitAA);
submit_propagation_for!(HitAD);
submit_propagation_for!(HitDA);
submit_propagation_for!(HitDD);
fn forward_hit_viewpoints(
base: On<Hit>,
q_character: Query<(), With<CharacterMarker>>,
mut commands: Commands,
) {
let attacker = base.attacker;
let defender = base.defender;
let attacker_is_char = q_character.get(attacker).is_ok();
let defender_is_char = q_character.get(defender).is_ok();
if attacker_is_char {
commands.trigger(HitAA {
target: attacker,
base: (*base).clone(),
});
commands.trigger(HitAD {
target: attacker,
base: (*base).clone(),
});
}
if defender_is_char {
commands.trigger(HitDA {
target: defender,
base: (*base).clone(),
});
commands.trigger(HitDD {
target: defender,
base: (*base).clone(),
});
}
}
#[derive(Component)]
pub struct ThornsEffect {
pub reflect_damage: f32,
}
#[derive(Component)]
pub struct CharacterMarker;
fn thorns_on_hit(
hit: On<HitDD>,
q_thorns: Query<&ThornsEffect>,
mut commands: Commands,
) {
let defender = hit.target;
let Ok(thorns) = q_thorns.get(defender) else {
return;
};
info!(
"Thorns: reflecting {:.1} damage back to {:?}",
thorns.reflect_damage, hit.base.attacker
);
let _ = commands; }
pub struct ViewpointPlugin;
impl Plugin for ViewpointPlugin {
fn build(&self, app: &mut App) {
app.add_observer(forward_hit_viewpoints)
.add_observer(thorns_on_hit);
bevy_diesel::propagation::plugin(app);
}
}
fn main() {
App::new()
.add_plugins(MinimalPlugins)
.add_plugins(ViewpointPlugin)
.run();
}