aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/client.rs29
-rw-r--r--src/shared/ability.rs35
-rw-r--r--src/shared/champion.rs6
3 files changed, 56 insertions, 14 deletions
diff --git a/src/client.rs b/src/client.rs
index b4213a2..ce48b4f 100644
--- a/src/client.rs
+++ b/src/client.rs
@@ -295,9 +295,7 @@ fn buffer_input(
let Some(position) = player_position(&client_id, &players) else {
return;
};
- let Some(direction) = (world_position - position.0).try_normalize() else {
- return;
- };
+ let direction = world_position - position.0;
client.add_input(Inputs::Imperative(Imperative::AttackDirection(
ability_slot,
direction,
@@ -340,6 +338,7 @@ fn buffer_input(
fn choose_attack(
champion: Res<MyChampion>,
keyboard_input: Res<ButtonInput<KeyCode>>,
+ mouse_input: Res<ButtonInput<MouseButton>>,
mut attack: ResMut<Attack>,
mut client: ClientMut,
) {
@@ -359,7 +358,9 @@ fn choose_attack(
attack.0 = Some(AbilitySlot::G);
} else if keyboard_input.just_pressed(KeyCode::Escape) {
attack.0 = None;
- } else if keyboard_input.just_pressed(KeyCode::ShiftLeft) {
+ } else if keyboard_input.just_pressed(KeyCode::CapsLock) {
+ attack.0 = None;
+ } else if mouse_input.just_pressed(MouseButton::Right) {
attack.0 = None;
}
match attack.0 {
@@ -459,20 +460,26 @@ fn gizmos_attack_indicator(
let Some(world_position) = cursor_world_position(&windows, &cameras) else {
return;
};
- let Some(direction) = (world_position - position.0).try_normalize() else {
- return;
- };
+ let direction = world_position - position.0;
match ability {
DirectionalAbility::Dash(Dash { max_distance, .. }) => {
let DashCollisionResult { dash_end, .. } = dash_collision(
PlayerId(client_id.0),
position.0,
- direction,
+ direction.normalize_or_zero(),
max_distance,
&player_positions,
);
gizmos.arrow_2d(position.0, dash_end, Color::YELLOW);
}
+ DirectionalAbility::Flash(Flash { max_distance, .. }) => {
+ gizmos.arrow_2d(
+ position.0,
+ position.0
+ + direction.length().min(max_distance) * direction.normalize_or_zero(),
+ Color::YELLOW,
+ );
+ }
DirectionalAbility::Pull(Pull { max_distance, .. }) => {
let Some(PullCollision {
pull_end,
@@ -481,12 +488,12 @@ fn gizmos_attack_indicator(
}) = pull_collision(
PlayerId(client_id.0),
position.0,
- direction,
+ direction.normalize_or_zero(),
max_distance,
&player_positions,
)
else {
- let pull_direction = -max_distance * direction;
+ let pull_direction = -max_distance * direction.normalize_or_zero();
let pull_start = position.0 - pull_direction;
let pull_end = pull_start
+ (pull_direction.length() - 2. * PLAYER_RADIUS)
@@ -499,7 +506,7 @@ fn gizmos_attack_indicator(
DirectionalAbility::Spear(Spear { max_distance, .. }) => {
gizmos.arrow_2d(
position.0,
- position.0 + max_distance * direction,
+ position.0 + max_distance * direction.normalize_or_zero(),
Color::YELLOW,
);
}
diff --git a/src/shared/ability.rs b/src/shared/ability.rs
index 8decfc6..b7b3664 100644
--- a/src/shared/ability.rs
+++ b/src/shared/ability.rs
@@ -180,6 +180,7 @@ fn speed_activation(speed: Speed) -> ActivatedAbilityActivation {
#[derive(Copy, Clone, PartialEq, Debug, Deserialize, Serialize)]
pub enum DirectionalAbility {
Dash(Dash),
+ Flash(Flash),
Pull(Pull),
Spear(Spear),
}
@@ -191,6 +192,11 @@ pub struct Dash {
}
#[derive(Copy, Clone, PartialEq, Debug, Deserialize, Serialize)]
+pub struct Flash {
+ pub max_distance: f32,
+}
+
+#[derive(Copy, Clone, PartialEq, Debug, Deserialize, Serialize)]
pub struct Pull {
pub max_distance: f32,
pub damage: f32,
@@ -202,18 +208,41 @@ pub struct Spear {
pub damage: f32,
}
+// `direction: Vec2` is NOT normalized (cf. `Flash`)!
pub type DirectionalAbilityActivation = Box<dyn FnOnce(&mut Commands, PlayerId, Vec2) -> ()>;
impl DirectionalAbility {
pub fn activate(self) -> DirectionalAbilityActivation {
match self {
DirectionalAbility::Dash(dash) => dash_activation(dash),
+ DirectionalAbility::Flash(flash) => flash_activation(flash),
DirectionalAbility::Pull(pull) => pull_activation(pull),
DirectionalAbility::Spear(spear) => spear_activation(spear),
}
}
}
+fn flash_activation(flash: Flash) -> DirectionalAbilityActivation {
+ Box::new(
+ move |commands: &mut Commands, source_player: PlayerId, direction: Vec2| {
+ commands.add(move |world: &mut World| {
+ world.run_system_once(
+ move |entity_map: Res<EntityMap>, mut positions: Query<&mut PlayerPosition>| {
+ let Some(entity_id) = entity_map.0.get(&source_player.0) else {
+ return;
+ };
+ let Ok(mut position) = positions.get_mut(*entity_id) else {
+ return;
+ };
+ position.0 += direction.length().min(flash.max_distance)
+ * direction.normalize_or_zero();
+ },
+ );
+ });
+ },
+ )
+}
+
fn dash_activation(dash: Dash) -> DirectionalAbilityActivation {
Box::new(
move |commands: &mut Commands, source_player: PlayerId, direction: Vec2| {
@@ -259,7 +288,7 @@ fn dash_activation(dash: Dash) -> DirectionalAbilityActivation {
dash_collision(
source_player,
source_position.0,
- direction,
+ direction.normalize_or_zero(),
dash.max_distance,
&dash_targets,
)
@@ -409,7 +438,7 @@ fn pull_activation(pull: Pull) -> DirectionalAbilityActivation {
pull_collision(
source_player,
source_position.0,
- direction,
+ direction.normalize_or_zero(),
pull.max_distance,
&pull_targets,
)
@@ -520,7 +549,7 @@ fn spear_activation(spear: Spear) -> DirectionalAbilityActivation {
commands.spawn(ProjectileBundle::new(Projectile {
type_: ProjectileType::Free(FreeProjectile {
position: position.0,
- direction,
+ direction: direction.normalize_or_zero(),
starting_position: position.0,
max_distance: spear.max_distance,
scale_damage: Some((0.75, 2.5)),
diff --git a/src/shared/champion.rs b/src/shared/champion.rs
index ecd6e10..f48faa1 100644
--- a/src/shared/champion.rs
+++ b/src/shared/champion.rs
@@ -64,6 +64,9 @@ impl Champion {
AbilitySlot::R => {
Ability::Targeted(TargetedAbility::MeeleAttack(MeeleAttack { damage: 45. }))
}
+ AbilitySlot::F => {
+ Ability::Directional(DirectionalAbility::Flash(Flash { max_distance: 100. }))
+ }
AbilitySlot::G => {
Ability::Activated(ActivatedAbility::Speed(Speed { duration: 2.5 }))
}
@@ -77,6 +80,9 @@ impl Champion {
AbilitySlot::R => {
Ability::Activated(ActivatedAbility::Focus(Focus { duration: 5. }))
}
+ AbilitySlot::F => {
+ Ability::Directional(DirectionalAbility::Flash(Flash { max_distance: 100. }))
+ }
AbilitySlot::G => {
Ability::Activated(ActivatedAbility::Speed(Speed { duration: 2.5 }))
}