55 lines
1.5 KiB
Rust
55 lines
1.5 KiB
Rust
use crate::prelude::*;
|
|
|
|
#[system]
|
|
#[read_component(WantsToAttack)]
|
|
#[read_component(Player)]
|
|
#[write_component(Health)]
|
|
#[read_component(Damage)]
|
|
#[read_component(Carried)]
|
|
pub fn combat(ecs: &mut SubWorld, commands: &mut CommandBuffer) {
|
|
let mut attackers = <(Entity, &WantsToAttack)>::query();
|
|
|
|
let victims: Vec<(Entity, Entity, Entity)> = attackers
|
|
.iter(ecs)
|
|
.map(|(entity, attack)| (*entity, attack.attacker, attack.victim))
|
|
.collect();
|
|
|
|
victims.iter().for_each(|(message, attacker, victim)| {
|
|
let base_damage = if let Ok(v) = ecs.entry_ref(*attacker) {
|
|
if let Ok(dmg) = v.get_component::<Damage>() {
|
|
dmg.0
|
|
} else {
|
|
0
|
|
}
|
|
} else {
|
|
0
|
|
};
|
|
|
|
let weapon_damage: i32 = <(&Carried, &Damage)>::query()
|
|
.iter(ecs)
|
|
.filter(|(carried, _)| carried.0 == *attacker)
|
|
.map(|(_, dmg)| dmg.0)
|
|
.sum();
|
|
|
|
let final_damage = base_damage + weapon_damage;
|
|
|
|
let is_player = ecs
|
|
.entry_ref(*victim)
|
|
.unwrap()
|
|
.get_component::<Player>()
|
|
.is_ok();
|
|
|
|
if let Ok(mut health) = ecs
|
|
.entry_mut(*victim)
|
|
.unwrap()
|
|
.get_component_mut::<Health>()
|
|
{
|
|
health.current -= final_damage;
|
|
if health.current < 1 && !is_player {
|
|
commands.remove(*victim);
|
|
}
|
|
}
|
|
commands.remove(*message);
|
|
});
|
|
}
|