From bb604c149aa76eaab261786a4cf5e7c977813a6d Mon Sep 17 00:00:00 2001
From: Louis Capitanchik <contact@louiscap.co>
Date: Mon, 3 Oct 2022 13:17:17 +0100
Subject: [PATCH] Create turns based on who can act

---
 game_core/src/control/ai.rs       |  2 ++
 game_core/src/control/mod.rs      |  7 ++++++
 game_core/src/control/player.rs   | 40 ++++++++++++++++++++++++-------
 game_core/src/debug.rs            | 38 ++++++++++++++++++++++++++---
 game_core/src/entities/spawner.rs |  2 ++
 5 files changed, 78 insertions(+), 11 deletions(-)

diff --git a/game_core/src/control/ai.rs b/game_core/src/control/ai.rs
index ba6e5cb..0724fbb 100644
--- a/game_core/src/control/ai.rs
+++ b/game_core/src/control/ai.rs
@@ -11,3 +11,5 @@ pub struct Meander;
 
 #[derive(Copy, Clone, Debug, Component)]
 pub struct ShouldAct;
+#[derive(Copy, Clone, Debug, Component)]
+pub struct Automated;
diff --git a/game_core/src/control/mod.rs b/game_core/src/control/mod.rs
index 09bbf08..d2f14fa 100644
--- a/game_core/src/control/mod.rs
+++ b/game_core/src/control/mod.rs
@@ -18,6 +18,13 @@ mod __plugin {
 					.run_in_state(AppState::InGame)
 					.with_system(super::player::handle_player_input)
 					.into(),
+			)
+			.add_system_set_to_stage(
+				CoreStage::PostUpdate,
+				ConditionSet::new()
+					.run_in_state(AppState::InGame)
+					.with_system(super::player::reset_player_action)
+					.into(),
 			);
 		}
 	}
diff --git a/game_core/src/control/player.rs b/game_core/src/control/player.rs
index 9d55493..63f571f 100644
--- a/game_core/src/control/player.rs
+++ b/game_core/src/control/player.rs
@@ -3,6 +3,7 @@ use std::time::Duration;
 use bevy::math::ivec2;
 use bevy::prelude::*;
 
+use crate::control::ai::{Automated, ShouldAct};
 use crate::entities::lifecycle::Player;
 use crate::entities::timing::ActionCooldown;
 use crate::world::level_map::GridPosition;
@@ -10,7 +11,11 @@ use crate::world::level_map::GridPosition;
 pub fn handle_player_input(
 	mut commands: Commands,
 	input: Res<Input<KeyCode>>,
-	mut query: Query<(Entity, &mut GridPosition), (With<Player>, Without<ActionCooldown>)>,
+	mut player_query: Query<
+		(Entity, &mut GridPosition),
+		(With<Player>, With<ShouldAct>, Without<ActionCooldown>),
+	>,
+	npc_query: Query<Entity, (With<Automated>, Without<ShouldAct>)>,
 ) {
 	let mut dx = 0;
 	let mut dy = 0;
@@ -28,13 +33,32 @@ pub fn handle_player_input(
 		dy -= 1;
 	}
 
-	for (entity, mut position) in &mut query {
-		if dx != 0 || dy != 0 {
-			let next_position = (position.0.as_ivec2()) + ivec2(dx, dy);
-			**position = next_position.as_uvec2();
-			commands
-				.entity(entity)
-				.insert(ActionCooldown::from(Duration::from_millis(250)));
+	if dx != 0 || dy != 0 {
+		for (entity, mut position) in &mut player_query {
+			if dx != 0 || dy != 0 {
+				let next_position = (position.0.as_ivec2()) + ivec2(dx, dy);
+				**position = next_position.as_uvec2();
+				commands
+					.entity(entity)
+					.insert(ActionCooldown::from(Duration::from_millis(250)))
+					.remove::<ShouldAct>();
+			}
+		}
+
+		for entity in &npc_query {
+			commands.entity(entity).insert(ShouldAct);
+		}
+	}
+}
+
+pub fn reset_player_action(
+	mut commands: Commands,
+	player_query: Query<Entity, (With<Player>, Without<ShouldAct>)>,
+	npc_query: Query<(), (With<Automated>, With<ShouldAct>)>,
+) {
+	if npc_query.iter().len() == 0 {
+		for entity in &player_query {
+			commands.entity(entity).insert(ShouldAct);
 		}
 	}
 }
diff --git a/game_core/src/debug.rs b/game_core/src/debug.rs
index 2216469..d6de11c 100644
--- a/game_core/src/debug.rs
+++ b/game_core/src/debug.rs
@@ -1,13 +1,14 @@
 use bevy::math::uvec2;
 use bevy::prelude::*;
-use iyes_loopless::prelude::AppLooplessStateExt;
+use iyes_loopless::prelude::{AppLooplessStateExt, ConditionSet};
 use iyes_loopless::state::NextState;
 
 use crate::assets::AssetHandles;
+use crate::entities::lifecycle::Player;
 use crate::system::flow::AppState;
 use crate::world::generators::blobular::Blobular;
 use crate::world::generators::drunkard_corridor::DrunkardGenerator;
-use crate::world::level_map::LevelMapBundle;
+use crate::world::level_map::{LevelMap, LevelMapBundle};
 
 pub fn spawn_player(mut commands: Commands) {
 	commands.spawn_bundle(LevelMapBundle::generate::<DrunkardGenerator>(150, 150));
@@ -68,12 +69,43 @@ pub fn skip_menu(mut commands: Commands) {
 	commands.insert_resource(NextState(AppState::InGame));
 }
 
+pub fn regen_map(
+	mut commands: Commands,
+	input: Res<Input<KeyCode>>,
+	map_query: Query<Entity, With<LevelMap>>,
+	player_query: Query<Entity, With<Player>>,
+) {
+	if input.just_pressed(KeyCode::Equals) {
+		for entity in &map_query {
+			commands.entity(entity).despawn_recursive();
+		}
+		for entity in &player_query {
+			commands.entity(entity).despawn_recursive();
+		}
+		commands.spawn_bundle(LevelMapBundle::generate::<DrunkardGenerator>(100, 100));
+	} else if input.just_pressed(KeyCode::Minus) {
+		for entity in &map_query {
+			commands.entity(entity).despawn_recursive();
+		}
+		for entity in &player_query {
+			commands.entity(entity).despawn_recursive();
+		}
+		commands.spawn_bundle(LevelMapBundle::generate::<Blobular>(100, 100));
+	}
+}
+
 pub struct DebugPlugin;
 impl Plugin for DebugPlugin {
 	fn build(&self, app: &mut App) {
 		app.add_enter_system(AppState::Menu, skip_menu)
 			.add_enter_system(AppState::Menu, spawn_fps_overlay)
 			.add_enter_system(AppState::InGame, spawn_player)
-			.add_system(update_fps_text);
+			.add_system(update_fps_text)
+			.add_system_set(
+				ConditionSet::new()
+					.run_in_state(AppState::InGame)
+					.with_system(regen_map)
+					.into(),
+			);
 	}
 }
diff --git a/game_core/src/entities/spawner.rs b/game_core/src/entities/spawner.rs
index 32bacc6..7547a74 100644
--- a/game_core/src/entities/spawner.rs
+++ b/game_core/src/entities/spawner.rs
@@ -2,6 +2,7 @@ use bevy::ecs::system::SystemParam;
 use bevy::prelude::*;
 
 use crate::assets::AssetHandles;
+use crate::control::ai::ShouldAct;
 use crate::entities::lifecycle::{GameEntity, Player};
 use crate::system::camera::ChaseCam;
 use crate::system::graphics::LAYER_CREATURE;
@@ -23,6 +24,7 @@ impl<'w, 's> EntitySpawner<'w, 's> {
 			.insert(ChaseCam)
 			.insert(GameEntity)
 			.insert(Player)
+			.insert(ShouldAct)
 			.insert(GridPosition(grid_position));
 
 		entity.insert_bundle(SpriteSheetBundle {
-- 
GitLab