diff options
Diffstat (limited to 'src/shared')
-rw-r--r-- | src/shared/ability.rs | 137 | ||||
-rw-r--r-- | src/shared/champion.rs | 2 |
2 files changed, 124 insertions, 15 deletions
diff --git a/src/shared/ability.rs b/src/shared/ability.rs index dd843e0..e8b2a26 100644 --- a/src/shared/ability.rs +++ b/src/shared/ability.rs @@ -1,6 +1,7 @@ use crate::shared::player::*; use crate::shared::projectile::*; use crate::shared::*; +use bevy::ecs::system::*; use bevy::utils::Duration; use std::ops::*; @@ -49,30 +50,138 @@ pub enum ActivatedAbility { #[derive(Copy, Clone, PartialEq, Debug, Deserialize, Serialize)] pub enum DirectionalAbility { + Dash, Spear, } +pub struct DirectionalAbilityActivation( + pub fn(commands: &mut Commands, source_player: PlayerId, direction: Vec2) -> (), +); + impl DirectionalAbility { - pub fn to_projectile( - self, - source_player: PlayerId, - position: Vec2, - direction: Vec2, - ) -> Projectile { + pub fn activate(self) -> DirectionalAbilityActivation { match self { - DirectionalAbility::Spear => Projectile { - type_: ProjectileType::Free(FreeProjectile { - position, - direction, - starting_position: position, - }), - source_player, - damage: 15., + DirectionalAbility::Dash => DirectionalAbilityActivation(dash_activation), + DirectionalAbility::Spear => DirectionalAbilityActivation(spear_activation), + } + } +} + +fn dash_activation(commands: &mut Commands, source_player: PlayerId, direction: Vec2) { + commands.add(move |world: &mut World| { + world.run_system_once( + move |players: Query<(Entity, &PlayerId)>, + mut set: ParamSet<( + Query<&mut PlayerPosition>, + Query<(&PlayerId, &PlayerPosition)>, + )>| { + let Some(source_entity) = ({ + let mut source_entity = None; + for (entity, player_id) in players.iter() { + if *player_id != source_player { + continue; + } + source_entity = Some(entity); + break; + } + source_entity + }) else { + return; + }; + + let Some(source_position) = ({ + let positions = set.p0(); + if let Ok(position) = positions.get(source_entity) { + Some(*position) + } else { + None + } + }) else { + return; + }; + + let dash_end = { + let dash_targets = set.p1(); + dash_collision( + source_player, + source_position.0, + direction, + 150., + &dash_targets, + ) + }; + + let mut positions = set.p0(); + if let Ok(mut position) = positions.get_mut(source_entity) { + position.0 = dash_end; + } }, + ) + }); +} + +pub fn dash_collision( + source_id: PlayerId, + dash_start: Vec2, + dash_direction: Vec2, + dash_max_distance: f32, + player_positions: &Query<(&PlayerId, &PlayerPosition)>, +) -> Vec2 { + let mut dash_collision = dash_max_distance * dash_direction; + let mut collision = false; + for (player_id, position) in player_positions.iter() { + if *player_id == source_id { + continue; + } + + let player_position = position.0 - dash_start; + let player_projection = player_position.project_onto(dash_collision); + let player_rejection = player_position - player_projection; + let scalar_factor = player_projection.dot(dash_collision).signum() + * player_projection.length() + / dash_collision.length(); + + if scalar_factor < 0. || scalar_factor > 1.0 { + continue; } + + if player_rejection.length() < 2. * PLAYER_RADIUS { + collision = true; + dash_collision = player_projection; + } + } + + if collision { + dash_start + + (dash_collision.length() - 2. * PLAYER_RADIUS) * dash_collision.normalize_or_zero() + } else { + dash_start + dash_max_distance * dash_direction } } +fn spear_activation(commands: &mut Commands, source_player: PlayerId, direction: Vec2) { + commands.add(move |world: &mut World| { + world.run_system_once( + move |mut commands: Commands, players: Query<(&PlayerId, &PlayerPosition)>| { + for (id, position) in players.iter() { + if *id != source_player { + continue; + } + commands.spawn(ProjectileBundle::new(Projectile { + type_: ProjectileType::Free(FreeProjectile { + position: position.0, + direction, + starting_position: position.0, + }), + source_player, + damage: 15., + })); + } + }, + ) + }); +} + #[derive(Debug, Serialize, Deserialize, Clone, Copy, PartialEq, Eq)] pub enum AbilitySlot { A, diff --git a/src/shared/champion.rs b/src/shared/champion.rs index c32d3d5..8dadd9b 100644 --- a/src/shared/champion.rs +++ b/src/shared/champion.rs @@ -30,7 +30,7 @@ impl Champion { pub fn to_ability(self, ability_slot: AbilitySlot) -> Ability { match self { Champion::Meele => match ability_slot { - AbilitySlot::Q => Ability::Directional(DirectionalAbility::Spear), + AbilitySlot::Q => Ability::Directional(DirectionalAbility::Dash), AbilitySlot::G => Ability::Activated(ActivatedAbility::Speed), _ => Ability::Targeted(TargetedAbility::MeeleAttack), }, |