From 890a8c764ae8e08a1dae7efe7b94d3f74280174e Mon Sep 17 00:00:00 2001 From: Carlo Supina Date: Wed, 18 Oct 2023 01:26:40 -0500 Subject: [PATCH 01/13] Add beam projectile type, and create get_faction function for projectile types --- assets/projectile_assets.assets.ron | 14 ++++++ crates/thetawave_interface/src/spawnable.rs | 12 ++++++ src/assets/projectile.rs | 10 +++++ src/collision/contact.rs | 47 +++++++-------------- src/collision/instersection.rs | 17 ++------ src/spawnable/projectile/behavior.rs | 1 + 6 files changed, 56 insertions(+), 45 deletions(-) diff --git a/assets/projectile_assets.assets.ron b/assets/projectile_assets.assets.ron index 7094cce2..1525835e 100644 --- a/assets/projectile_assets.assets.ron +++ b/assets/projectile_assets.assets.ron @@ -34,4 +34,18 @@ columns: 1, rows: 1, ), + "ally_beam": TextureAtlas ( + path: "texture/ally_beam.png", + tile_size_x: 5., + tile_size_y: 1., + columns: 1, + rows: 1, + ), + "enemy_beam": TextureAtlas( + path: "texture/enemy_beam.png", + tile_size_x: 5., + tile_size_y: 1., + columns: 1, + rows: 1, + ), }) \ No newline at end of file diff --git a/crates/thetawave_interface/src/spawnable.rs b/crates/thetawave_interface/src/spawnable.rs index c9788d8b..1395032c 100644 --- a/crates/thetawave_interface/src/spawnable.rs +++ b/crates/thetawave_interface/src/spawnable.rs @@ -44,6 +44,18 @@ impl Default for SpawnableType { pub enum ProjectileType { Blast(Faction), Bullet(Faction), + Beam(Faction), +} + +impl ProjectileType { + pub fn get_faction(&self) -> Faction { + match self { + ProjectileType::Blast(faction) => faction, + ProjectileType::Bullet(faction) => faction, + ProjectileType::Beam(faction) => faction, + } + .clone() + } } /// Factions diff --git a/src/assets/projectile.rs b/src/assets/projectile.rs index 248b56f5..3ddb1a41 100644 --- a/src/assets/projectile.rs +++ b/src/assets/projectile.rs @@ -14,6 +14,10 @@ pub struct ProjectileAssets { pub ally_bullet: Handle, #[asset(key = "enemy_bullet")] pub enemy_bullet: Handle, + #[asset(key = "ally_beam")] + pub ally_beam: Handle, + #[asset(key = "enemy_beam")] + pub enemy_beam: Handle, } impl ProjectileAssets { @@ -29,12 +33,18 @@ impl ProjectileAssets { Faction::Enemy => self.enemy_bullet.clone(), Faction::Neutral => todo!(), }, + ProjectileType::Beam(faction) => match faction { + Faction::Ally => self.ally_beam.clone(), + Faction::Enemy => self.enemy_beam.clone(), + Faction::Neutral => todo!(), + }, } } pub fn get_color(&self, projectile_type: &ProjectileType) -> Color { match projectile_type { ProjectileType::Blast(_) => Color::rgb(3.0, 3.0, 3.0), ProjectileType::Bullet(_) => Color::rgb(2.0, 2.0, 2.0), + ProjectileType::Beam(_) => Color::rgb(3.0, 3.0, 3.0), } } } diff --git a/src/collision/contact.rs b/src/collision/contact.rs index 9baf56e9..d15d3bf0 100644 --- a/src/collision/contact.rs +++ b/src/collision/contact.rs @@ -105,10 +105,7 @@ pub fn contact_collision_system( collision_event_writer.send(SortedCollisionEvent::PlayerToProjectileContact { player_entity: colliding_entities.primary, projectile_entity: colliding_entities.secondary, - projectile_faction: match projectile_component.projectile_type.clone() { - ProjectileType::Blast(faction) => faction, - ProjectileType::Bullet(faction) => faction, - }, + projectile_faction: projectile_component.projectile_type.get_faction(), player_damage: player_component.collision_damage, projectile_damage: projectile_component.damage, }); @@ -226,10 +223,7 @@ pub fn contact_collision_system( projectile_source: projectile_component.source, mob_entity: colliding_entities.primary, projectile_entity: colliding_entities.secondary, - projectile_faction: match &projectile_component.projectile_type { - ProjectileType::Blast(faction) => faction.clone(), - ProjectileType::Bullet(faction) => faction.clone(), - }, + projectile_faction: projectile_component.projectile_type.get_faction(), mob_faction: match mob_component_1.mob_type { MobType::Enemy(_) => Faction::Enemy, MobType::Ally(_) => Faction::Ally, @@ -311,10 +305,7 @@ pub fn contact_collision_system( SortedCollisionEvent::MobSegmentToProjectileContact { mob_segment_entity: colliding_entities.primary, projectile_entity: colliding_entities.secondary, - projectile_faction: match &projectile_component.projectile_type { - ProjectileType::Blast(faction) => faction.clone(), - ProjectileType::Bullet(faction) => faction.clone(), - }, + projectile_faction: projectile_component.projectile_type.get_faction(), mob_segment_faction: match mob_segment_component_1.mob_segment_type { MobSegmentType::Enemy(_) => Faction::Enemy, MobSegmentType::Neutral(_) => Faction::Neutral, @@ -350,33 +341,25 @@ pub fn contact_collision_system( collision_event_writer.send( SortedCollisionEvent::ProjectileToProjectileContact { projectile_entity_1, - projectile_faction_1: match &projectile_component_1.projectile_type - { - ProjectileType::Blast(faction) => faction.clone(), - ProjectileType::Bullet(faction) => faction.clone(), - }, + projectile_faction_1: projectile_component_1 + .projectile_type + .get_faction(), projectile_entity_2, - projectile_faction_2: match &projectile_component_1.projectile_type - { - ProjectileType::Blast(faction) => faction.clone(), - ProjectileType::Bullet(faction) => faction.clone(), - }, + projectile_faction_2: projectile_component_1 + .projectile_type + .get_faction(), }, ); collision_event_writer.send( SortedCollisionEvent::ProjectileToProjectileContact { projectile_entity_1: projectile_entity_2, - projectile_faction_1: match &projectile_component_2.projectile_type - { - ProjectileType::Blast(faction) => faction.clone(), - ProjectileType::Bullet(faction) => faction.clone(), - }, + projectile_faction_1: projectile_component_2 + .projectile_type + .get_faction(), projectile_entity_2: projectile_entity_1, - projectile_faction_2: match &projectile_component_1.projectile_type - { - ProjectileType::Blast(faction) => faction.clone(), - ProjectileType::Bullet(faction) => faction.clone(), - }, + projectile_faction_2: projectile_component_1 + .projectile_type + .get_faction(), }, ); continue 'collision_events; diff --git a/src/collision/instersection.rs b/src/collision/instersection.rs index 1423b62c..ad21e4f9 100644 --- a/src/collision/instersection.rs +++ b/src/collision/instersection.rs @@ -5,7 +5,7 @@ use bevy::prelude::*; use bevy_rapier2d::{prelude::*, rapier::prelude::CollisionEventFlags}; use thetawave_interface::{ player::PlayerComponent, - spawnable::{Faction, ItemComponent, MobSegmentType, MobType, ProjectileType}, + spawnable::{Faction, ItemComponent, MobSegmentType, MobType}, }; use super::{CollidingEntityPair, SortedCollisionEvent}; @@ -59,10 +59,7 @@ pub fn intersection_collision_system( SortedCollisionEvent::PlayerToProjectileIntersection { player_entity: colliding_entities.primary, projectile_entity: colliding_entities.secondary, - projectile_faction: match projectile_component.projectile_type.clone() { - ProjectileType::Blast(faction) => faction, - ProjectileType::Bullet(faction) => faction, - }, + projectile_faction: projectile_component.projectile_type.get_faction(), projectile_damage: projectile_component.damage, }, ); @@ -105,10 +102,7 @@ pub fn intersection_collision_system( MobType::Ally(_) => Faction::Ally, MobType::Neutral(_) => Faction::Neutral, }, - projectile_faction: match projectile_component.projectile_type.clone() { - ProjectileType::Blast(faction) => faction, - ProjectileType::Bullet(faction) => faction, - }, + projectile_faction: projectile_component.projectile_type.get_faction(), projectile_damage: projectile_component.damage, }, ); @@ -131,10 +125,7 @@ pub fn intersection_collision_system( MobSegmentType::Neutral(_) => Faction::Neutral, MobSegmentType::Enemy(_) => Faction::Enemy, }, - projectile_faction: match projectile_component.projectile_type.clone() { - ProjectileType::Blast(faction) => faction, - ProjectileType::Bullet(faction) => faction, - }, + projectile_faction: projectile_component.projectile_type.get_faction(), projectile_damage: projectile_component.damage, }, ); diff --git a/src/spawnable/projectile/behavior.rs b/src/spawnable/projectile/behavior.rs index 82c18a36..9a1d5b79 100644 --- a/src/spawnable/projectile/behavior.rs +++ b/src/spawnable/projectile/behavior.rs @@ -137,6 +137,7 @@ pub fn projectile_execute_behavior_system( } _ => {} }, + ProjectileType::Beam(_) => todo!(), } commands.entity(entity).despawn_recursive(); From 79c5520086ffa30b4cafa2b1e87a4d61b20b46fe Mon Sep 17 00:00:00 2001 From: Carlo Supina Date: Thu, 19 Oct 2023 23:34:52 -0500 Subject: [PATCH 02/13] splite projectile behavior megasystem into individual behaviors and systems --- src/spawnable/mod.rs | 8 +- src/spawnable/projectile/behavior.rs | 712 +++++++++++++-------------- src/spawnable/projectile/mod.rs | 38 +- 3 files changed, 387 insertions(+), 371 deletions(-) diff --git a/src/spawnable/mod.rs b/src/spawnable/mod.rs index 09487167..9d027eb4 100644 --- a/src/spawnable/mod.rs +++ b/src/spawnable/mod.rs @@ -24,9 +24,10 @@ mod projectile; use self::behavior::attract_to_player_system; use self::item::ItemPlugin; pub use self::mob::*; +use self::projectile::ProjectilePlugin; pub use self::projectile::{ - projectile_execute_behavior_system, spawn_projectile_system, ProjectileComponent, - ProjectileData, ProjectileResource, SpawnProjectileEvent, + spawn_projectile_system, ProjectileComponent, ProjectileData, ProjectileResource, + SpawnProjectileEvent, }; pub use self::behavior::{ @@ -87,7 +88,7 @@ impl Plugin for SpawnablePlugin { .add_event::() .add_event::(); - app.add_plugins((EffectPlugin, ItemPlugin)); + app.add_plugins((EffectPlugin, ItemPlugin, ProjectilePlugin)); app.add_systems( Update, @@ -101,7 +102,6 @@ impl Plugin for SpawnablePlugin { mob_segment_apply_disconnected_behaviors_system .in_set(GameUpdateSet::ApplyDisconnectedBehaviors), mob_segment_execute_behavior_system.in_set(GameUpdateSet::ExecuteBehavior), - projectile_execute_behavior_system.in_set(GameUpdateSet::ExecuteBehavior), consumable_execute_behavior_system.in_set(GameUpdateSet::ExecuteBehavior), spawn_projectile_system, spawn_consumable_system, // event generated in mob execute behavior diff --git a/src/spawnable/projectile/behavior.rs b/src/spawnable/projectile/behavior.rs index 9a1d5b79..2e77d375 100644 --- a/src/spawnable/projectile/behavior.rs +++ b/src/spawnable/projectile/behavior.rs @@ -1,5 +1,5 @@ use crate::{ - collision::SortedCollisionEvent, + collision::{self, SortedCollisionEvent}, spawnable::{MobComponent, MobSegmentComponent, SpawnEffectEvent}, }; use bevy::prelude::*; @@ -9,10 +9,43 @@ use thetawave_interface::{ health::DamageDealtEvent, player::PlayerComponent, spawnable::{EffectType, Faction, ProjectileType}, + states, }; use super::ProjectileComponent; +pub struct ProjectileBehaviorPlugin; + +impl Plugin for ProjectileBehaviorPlugin { + fn build(&self, app: &mut App) { + app.add_systems( + Update, + ( + deal_damage_on_intersection_system, + explode_on_intersection_system, + ) + .run_if(in_state(states::AppStates::Game)) + .run_if(in_state(states::GameStates::Playing)) + .chain(), + ); + + app.add_systems( + Update, + (deal_damage_on_contact_system, explode_on_contact_system) + .run_if(in_state(states::AppStates::Game)) + .run_if(in_state(states::GameStates::Playing)) + .chain(), + ); + + app.add_systems( + Update, + timed_despawn_system + .run_if(in_state(states::AppStates::Game)) + .run_if(in_state(states::GameStates::Playing)), + ); + } +} + /// Types of behaviors that can be performed by projectiles #[derive(Deserialize, Clone)] pub enum ProjectileBehavior { @@ -23,140 +56,29 @@ pub enum ProjectileBehavior { TimedDespawn { despawn_time: f32 }, } -/// Manages executing behaviors of mobs -#[allow(clippy::too_many_arguments)] -pub fn projectile_execute_behavior_system( - mut commands: Commands, - mut projectile_query: Query<(Entity, &Transform, &mut ProjectileComponent)>, - player_query: Query<(Entity, &PlayerComponent)>, - mut mob_query: Query<(Entity, &mut MobComponent)>, - mut mob_segment_query: Query<(Entity, &mut MobSegmentComponent)>, - mut collision_events: EventReader, - mut spawn_effect_event_writer: EventWriter, - time: Res