diff options
Diffstat (limited to 'src/server.rs')
-rw-r--r-- | src/server.rs | 87 |
1 files changed, 80 insertions, 7 deletions
diff --git a/src/server.rs b/src/server.rs index 4da2253..fa761fa 100644 --- a/src/server.rs +++ b/src/server.rs @@ -11,6 +11,7 @@ use crate::shared::health::*; use crate::shared::health_event::*; use crate::shared::immovable::*; use crate::shared::imperative::*; +use crate::shared::minion::*; use crate::shared::player::*; use crate::shared::projectile::*; use crate::shared::shape::*; @@ -91,17 +92,45 @@ impl Plugin for ServerPlugin { .add_systems(FixedUpdate, cooldown_decrement) .add_systems(FixedUpdate, (buffs_despawn, buffs_tick).chain()) .add_systems(FixedUpdate, player_input) - .add_systems(FixedUpdate, tower_ai); + .add_systems( + FixedUpdate, + (tower_ai, minion_ai).before(imperative_attack_approach), + ) + .add_systems(FixedUpdate, minion_despawn); } } fn setup(mut commands: Commands, mut entity_map: ResMut<EntityMap>) { - let entity = commands.spawn(PlayerBundle::new(1, Vec2::ZERO, Color::GRAY)); - entity_map.0.insert(1, entity.id()); - let entity = commands.spawn(TowerBundle::new(2, Vec2::new(0., 100.), Color::RED)); - entity_map.0.insert(2, entity.id()); - let entity = commands.spawn(TowerBundle::new(3, Vec2::new(0., -100.), Color::BLUE)); - entity_map.0.insert(3, entity.id()); + { + let entity_id = 1; + let entity = commands.spawn(TowerBundle::new(entity_id, Vec2::new(0., 100.), Color::RED)); + entity_map.0.insert(entity_id, entity.id()); + } + { + let entity_id = 2; + let entity = commands.spawn(TowerBundle::new( + entity_id, + Vec2::new(0., -100.), + Color::BLUE, + )); + entity_map.0.insert(entity_id, entity.id()); + } + for entity_id in 3..=8 { + let entity = commands.spawn(MinionBundle::new( + entity_id, + Vec2::new((entity_id - 2) as f32 * 25., 0.), + Color::BLUE, + )); + entity_map.0.insert(entity_id, entity.id()); + } + for entity_id in 9..=14 { + let entity = commands.spawn(MinionBundle::new( + entity_id, + Vec2::new((entity_id - 8) as f32 * -25., 0.), + Color::RED, + )); + entity_map.0.insert(entity_id, entity.id()); + } } fn connects( @@ -707,3 +736,47 @@ fn tower_ai( tower_tower.last_target_player_id = Some(*target_player_id); } } + +fn minion_ai( + mut minions: Query< + (&PlayerId, &mut Imperative, &PlayerPosition, &EffectiveStats), + With<Minion>, + >, + targets: Query<(&PlayerId, &PlayerPosition, &Shape)>, +) { + for (minion_player_id, mut minion_imperative, minion_player_position, minion_effective_stats) in + minions.iter_mut() + { + let mut closest_target = None; + for (target_player_id, target_player_position, target_shape) in targets.iter() { + if target_player_id == minion_player_id { + continue; + } + let target_in_range = minion_player_position.0.distance(target_player_position.0) + < minion_effective_stats.0.attack_range + target_shape.radius; + if !target_in_range { + continue; + } + let target_distance = minion_player_position.0.distance(target_player_position.0); + let target_is_closer = closest_target + .map(|(_, closest_target_distance)| target_distance < closest_target_distance) + .unwrap_or(true); + if target_is_closer { + closest_target = Some((target_player_id, target_distance)); + } + } + let Some((target_player_id, _)) = closest_target else { + *minion_imperative = Imperative::Idle; + continue; + }; + *minion_imperative = Imperative::AttackTarget(AbilitySlot::A, *target_player_id); + } +} + +fn minion_despawn(minions: Query<(Entity, &Health), With<Minion>>, mut commands: Commands) { + for (minion_entity, minion_health) in minions.iter() { + if minion_health.health <= 0. { + commands.entity(minion_entity).despawn() + } + } +} |