diff --git a/src/enter_stage/systems.rs b/src/enter_stage/systems.rs index d28bfcd..96e401e 100644 --- a/src/enter_stage/systems.rs +++ b/src/enter_stage/systems.rs @@ -1,7 +1,7 @@ use std::time::Duration; use crate::{ - game::prelude::{EnemySpawn, SplitTimer, Stage, StageHandle, Wave}, + game::prelude::{EnemySpawn, SplitTimer, Stage, StageHandle, Wave, WaveSpawnCount}, GameState, }; use bevy::prelude::*; @@ -31,6 +31,7 @@ pub fn setup_resources( Duration::from_millis((stage.split_interval_secs(0) * 1000.0) as u64), TimerMode::Repeating, ))); + commands.insert_resource(WaveSpawnCount(0)); } pub fn show_stage_intro( diff --git a/src/game/components.rs b/src/game/components.rs index acba8c2..a6df4b4 100644 --- a/src/game/components.rs +++ b/src/game/components.rs @@ -4,6 +4,7 @@ use bevy::{prelude::*, utils::HashSet}; use derive_more::From; pub const PLAYER_MISSILE_SPEED: f32 = 250.0; +pub const MAX_AMMO: u8 = 30; #[derive(From)] pub enum Scoring { @@ -171,7 +172,7 @@ pub struct TextColor; #[derive(Component)] pub struct DropBombTimer(pub Timer); #[derive(Component)] -pub struct MissileReserve(pub usize); +pub struct MissileReserve(pub u8); #[derive(Component)] pub struct City; #[derive(Component)] diff --git a/src/game/mod.rs b/src/game/mod.rs index 03a2580..5a19aeb 100644 --- a/src/game/mod.rs +++ b/src/game/mod.rs @@ -7,9 +7,10 @@ use self::{ systems::{ ammo_ui, animate_sprite_indices, animate_sprite_steps, change_colors, defeat, drop_bombs, explode_city, explosion_event_listener_system, explosion_system, flame_engulf_system, - game_keys, game_over_ui, gizmo_missile_trails, missile_arrival_event_listner, move_cursor, - move_missile, move_ufo, reset_game_listener, rotate_player, score_ui, setup_player, - spawn_enemies, split_missiles, teardown, wave_ui, + game_keys, game_over_ui, gizmo_missile_trails, is_wave_finished, + missile_arrival_event_listner, move_cursor, move_missile, move_ufo, reset_game_listener, + rotate_player, score_ui, setup_player, spawn_enemies, split_missiles, teardown, + wave_complete, wave_ui, }, }; use crate::GameState; @@ -46,7 +47,9 @@ impl Plugin for GamePlugin { flick_system, change_colors, ( - spawn_enemies, + spawn_enemies.run_if( + in_state(GameState::InGame).and_then(not(is_wave_finished)), + ), split_missiles, move_missile, gizmo_missile_trails, @@ -63,6 +66,8 @@ impl Plugin for GamePlugin { rotate_player, defeat, stage_colors.after(spawn_enemies), + (wave_complete) + .run_if(in_state(GameState::InGame).and_then(is_wave_finished)), ) .run_if(in_state(GameState::InGame)), // run these systems if we are in the GameOver state diff --git a/src/game/prelude.rs b/src/game/prelude.rs index 4b1e01e..7925088 100644 --- a/src/game/prelude.rs +++ b/src/game/prelude.rs @@ -114,3 +114,5 @@ pub struct EnemySpawn(pub Timer); #[derive(Resource)] pub struct SplitTimer(pub Timer); +#[derive(Resource)] +pub struct WaveSpawnCount(pub usize); diff --git a/src/game/systems.rs b/src/game/systems.rs index c68f50a..b908a09 100644 --- a/src/game/systems.rs +++ b/src/game/systems.rs @@ -15,10 +15,10 @@ use super::{ City, Cursor, Destroyed, DropBombTimer, Enemy, Engulfable, Explodable, Explosion, ExplosionEvent, ExplosionMode, FlameRadius, Foreground, Health, IdCounter, Missile, MissileArrivalEvent, MissileReserve, Player, Score, Scoring, SpawnPoint, Stepper, - TargetLock, Ufo, PLAYER_MISSILE_SPEED, + TargetLock, Ufo, MAX_AMMO, PLAYER_MISSILE_SPEED, }, effects::{Flick, TimedRemoval}, - prelude::{color_from_vec, EnemySpawn, SplitTimer, Stage, StageHandle, Wave}, + prelude::{color_from_vec, EnemySpawn, SplitTimer, Stage, StageHandle, Wave, WaveSpawnCount}, }; pub fn game_keys( @@ -198,6 +198,28 @@ pub fn split_missiles( } } +pub fn is_wave_finished( + stage: Res, + stages: Res>, + wave: Res, + spawn_count: Res, +) -> bool { + let stage = stages.get(&stage.0).unwrap(); + stage.enemies_count(wave.0) <= spawn_count.0 +} + +pub fn wave_complete( + mut wave: ResMut, + mut spawn_count: ResMut, + mut missile_ammo: Query<&mut MissileReserve, With>, +) { + wave.0 += 1; + spawn_count.0 = 0; + for mut ammo in missile_ammo.iter_mut() { + ammo.0 = MAX_AMMO; + } +} + pub fn spawn_enemies( mut id_counter: ResMut, mut commands: Commands, @@ -208,6 +230,7 @@ pub fn spawn_enemies( stage: Res, stages: Res>, wave: Res, + mut spawn_count: ResMut, ) { enemy_spawn.0.tick(time.delta()); @@ -217,12 +240,13 @@ pub fn spawn_enemies( enemy_spawn.0.reset(); - let mut rng = RngComponent::from(&mut global_rng); let stage = stages.get(&stage.0).unwrap(); + let mut rng = RngComponent::from(&mut global_rng); // spawn ufo if rng.chance(stage.ufo_chance(wave.0)) { spawner::ufo(&mut commands, &mut rng, images.cursor.clone()); + spawn_count.0 += 1; } for _ in 0..=rng.usize(stage.missile_spawn_min(wave.0)..stage.missile_spawn_max(wave.0)) { @@ -234,6 +258,7 @@ pub fn spawn_enemies( &stage, None, ); + spawn_count.0 += 1; } } @@ -652,7 +677,7 @@ pub fn setup_player(mut commands: Commands, images: Res) { Player, Cannon, Health { max: 3, current: 3 }, - MissileReserve(30), + MissileReserve(MAX_AMMO), Foreground, )) .id();