diff options
author | Alexander Foremny <aforemny@posteo.de> | 2024-03-18 04:19:34 +0100 |
---|---|---|
committer | Alexander Foremny <aforemny@posteo.de> | 2024-03-18 04:19:34 +0100 |
commit | 937e1ed8d240c1a5b42f5b8cf1104321b9d79c4a (patch) | |
tree | c9cc6f8ec35e3e9b1ba97b5fd42091cf0ab2afb6 /src | |
parent | ab675360c0005718a3c9b8b5e7962af897269c04 (diff) |
fix: fix abilities selecting the right cooldown
Diffstat (limited to 'src')
-rw-r--r-- | src/client.rs | 98 | ||||
-rw-r--r-- | src/server.rs | 42 | ||||
-rw-r--r-- | src/shared/ability.rs | 53 | ||||
-rw-r--r-- | src/shared/champion.rs | 10 | ||||
-rw-r--r-- | src/shared/cooldown.rs | 17 | ||||
-rw-r--r-- | src/shared/imperative.rs | 15 |
6 files changed, 118 insertions, 117 deletions
diff --git a/src/client.rs b/src/client.rs index e3c4594..7ccced7 100644 --- a/src/client.rs +++ b/src/client.rs @@ -47,7 +47,7 @@ struct ClientId(pub u64); struct MyChampion(pub Champion); #[derive(Resource)] -struct Attack(Option<AttackKey>); +struct Attack(Option<AbilitySlot>); struct ClientPlugin { pub server_addr: Option<SocketAddr>, @@ -100,26 +100,10 @@ impl Plugin for ClientPlugin { } #[derive(Component, PartialEq, Eq, Debug)] -pub enum Hotbar { - A, - Q, - W, - E, - R, - F, - G, -} +pub struct Hotbar(AbilitySlot); #[derive(Component, PartialEq, Eq, Debug)] -pub enum HotbarCooldown { - A, - Q, - W, - E, - R, - F, - G, -} +pub struct HotbarCooldown(AbilitySlot); fn setup(mut client: ClientMut, mut commands: Commands, champion: Res<MyChampion>) { commands.spawn(Camera2dBundle::default()); @@ -137,7 +121,10 @@ fn setup(mut client: ClientMut, mut commands: Commands, champion: Res<MyChampion ..Default::default() }) .with_children(|builder| { - let mut hotkey = |label, hotbar, hotbar_cooldown| { + let mut hotkey = |ability_slot: AbilitySlot| { + let label = ability_slot.to_label(); + let hotbar = Hotbar(ability_slot); + let hotbar_cooldown = HotbarCooldown(ability_slot); builder .spawn(NodeBundle { style: Style { @@ -186,13 +173,9 @@ fn setup(mut client: ClientMut, mut commands: Commands, champion: Res<MyChampion )); }); }; - hotkey("A", Hotbar::A, HotbarCooldown::A); - hotkey("Q", Hotbar::Q, HotbarCooldown::Q); - hotkey("W", Hotbar::W, HotbarCooldown::W); - hotkey("E", Hotbar::E, HotbarCooldown::E); - hotkey("R", Hotbar::R, HotbarCooldown::R); - hotkey("F", Hotbar::F, HotbarCooldown::F); - hotkey("G", Hotbar::G, HotbarCooldown::G); + for ability_slot in AbilitySlot::all() { + hotkey(ability_slot); + } }); client.connect().unwrap(); client @@ -273,7 +256,7 @@ fn buffer_input( if mouse_input.just_pressed(MouseButton::Left) { match attack.0 { Some(attack_key) => match champion.0.to_ability(attack_key) { - Ability::Directional(ability) => { + Ability::Directional(_) => { let Some(world_position) = cursor_world_position(&windows, &cameras) else { return; }; @@ -284,18 +267,18 @@ fn buffer_input( return; }; client.add_input(Inputs::Imperative(Imperative::AttackDirection( - ability, direction, + attack_key, direction, ))); attack.0 = None; } - Ability::Targeted(ability) => { + Ability::Targeted(_) => { let Some((target_player, _)) = hovered_other_player(&cameras, &client_id, &players, &windows) else { return; }; client.add_input(Inputs::Imperative(Imperative::AttackTarget( - ability, + attack_key, target_player, ))); attack.0 = None; @@ -306,7 +289,7 @@ fn buffer_input( hovered_other_player(&cameras, &client_id, &players, &windows) { client.add_input(Inputs::Imperative(Imperative::AttackTarget( - TargetedAbility::MeeleAttack, + AbilitySlot::A, target_player, ))); } else { @@ -321,19 +304,19 @@ fn buffer_input( fn choose_attack(keyboard_input: Res<ButtonInput<KeyCode>>, mut attack_key: ResMut<Attack>) { if keyboard_input.just_pressed(KeyCode::KeyA) { - attack_key.0 = Some(AttackKey::A); + attack_key.0 = Some(AbilitySlot::A); } else if keyboard_input.just_pressed(KeyCode::KeyQ) { - attack_key.0 = Some(AttackKey::Q); + attack_key.0 = Some(AbilitySlot::Q); } else if keyboard_input.just_pressed(KeyCode::KeyW) { - attack_key.0 = Some(AttackKey::W); + attack_key.0 = Some(AbilitySlot::W); } else if keyboard_input.just_pressed(KeyCode::KeyE) { - attack_key.0 = Some(AttackKey::E); + attack_key.0 = Some(AbilitySlot::E); } else if keyboard_input.just_pressed(KeyCode::KeyR) { - attack_key.0 = Some(AttackKey::R); + attack_key.0 = Some(AbilitySlot::R); } else if keyboard_input.just_pressed(KeyCode::KeyF) { - attack_key.0 = Some(AttackKey::F); + attack_key.0 = Some(AbilitySlot::F); } else if keyboard_input.just_pressed(KeyCode::KeyG) { - attack_key.0 = Some(AttackKey::G); + attack_key.0 = Some(AbilitySlot::G); } else if keyboard_input.just_pressed(KeyCode::Escape) { attack_key.0 = None; } @@ -413,7 +396,7 @@ fn gizmos_attack_indicator( return; }; let Some(attack_key) = attack.0.or_else(|| { - hovered_other_player(&cameras, &client_id, &hoverables, &windows).map(|_| AttackKey::A) + hovered_other_player(&cameras, &client_id, &hoverables, &windows).map(|_| AbilitySlot::A) }) else { return; }; @@ -480,16 +463,7 @@ fn hotbar_cooldown( return; }; for (hotbar_cooldown, mut text, mut style) in hotbar_cooldowns.iter_mut() { - let cooldown = (match hotbar_cooldown { - HotbarCooldown::A => cooldown.a_cooldown, - HotbarCooldown::Q => cooldown.q_cooldown, - HotbarCooldown::W => cooldown.w_cooldown, - HotbarCooldown::E => cooldown.e_cooldown, - HotbarCooldown::R => cooldown.r_cooldown, - HotbarCooldown::F => cooldown.f_cooldown, - HotbarCooldown::G => cooldown.g_cooldown, - }) - .as_secs_f32(); + let cooldown = cooldown.0[hotbar_cooldown.0].as_secs_f32(); if text.sections.len() <= 0 { continue; } @@ -523,17 +497,7 @@ fn hotbar_hotbar_display( return; }; for (hotbar, mut style) in hotbars.iter_mut() { - let cooldown = (match hotbar { - Hotbar::A => cooldown.a_cooldown, - Hotbar::Q => cooldown.q_cooldown, - Hotbar::W => cooldown.w_cooldown, - Hotbar::E => cooldown.e_cooldown, - Hotbar::R => cooldown.r_cooldown, - Hotbar::F => cooldown.f_cooldown, - Hotbar::G => cooldown.g_cooldown, - }) - .as_secs_f32(); - if cooldown <= 0. { + if cooldown.0[hotbar.0].as_secs_f32() <= 0. { style.display = Display::Flex; } else { style.display = Display::None; @@ -542,19 +506,11 @@ fn hotbar_hotbar_display( } fn hotbar_hotbar_highlight(attack: Res<Attack>, mut hotbars: Query<(&Hotbar, &mut Text)>) { - let Some(attack_key) = attack.0 else { + let Some(ability_slot) = attack.0 else { return; }; for (hotbar, mut text) in hotbars.iter_mut() { - let is_highlighted = match attack_key { - AttackKey::A => *hotbar == Hotbar::A, - AttackKey::Q => *hotbar == Hotbar::Q, - AttackKey::W => *hotbar == Hotbar::W, - AttackKey::E => *hotbar == Hotbar::E, - AttackKey::R => *hotbar == Hotbar::R, - AttackKey::F => *hotbar == Hotbar::F, - AttackKey::G => *hotbar == Hotbar::G, - }; + let is_highlighted = ability_slot == hotbar.0; if text.sections.len() <= 0 { continue; } diff --git a/src/server.rs b/src/server.rs index 165c5f0..038f854 100644 --- a/src/server.rs +++ b/src/server.rs @@ -1,5 +1,6 @@ use crate::protocol::*; use crate::server::network::*; +use crate::shared::ability::*; use crate::shared::champion::*; use crate::shared::cooldown::*; use crate::shared::health::*; @@ -9,7 +10,6 @@ use crate::shared::player::*; use crate::shared::projectile::*; use crate::shared::*; use bevy::prelude::*; -use bevy::utils::Duration; use bevy::utils::HashMap; use lightyear::prelude::*; use lightyear::server::events::MessageEvent; @@ -247,13 +247,17 @@ fn imperative_attack_attack( champions: Query<&Champion>, ) { for (id, mut imperative) in players.iter_mut() { + let Some(entity) = entity_map.0.get(&id.0) else { + *imperative = Imperative::Idle; + return; + }; + let Ok(champion) = champions.get(*entity) else { + *imperative = Imperative::Idle; + return; + }; match *imperative { - Imperative::AttackTarget(ability, target_player) => { - let Some(entity) = entity_map.0.get(&id.0) else { - *imperative = Imperative::Idle; - return; - }; - let Ok(champion) = champions.get(*entity) else { + Imperative::AttackTarget(ability_slot, target_player) => { + let Ability::Targeted(ability) = champion.to_ability(ability_slot) else { *imperative = Imperative::Idle; return; }; @@ -273,8 +277,9 @@ fn imperative_attack_attack( *imperative = Imperative::Idle; return; }; - if cooldown.a_cooldown.is_zero() { - cooldown.a_cooldown = Duration::from_secs_f32(1.5); + let base_cooldown = BaseCooldown::from_champion(*champion); + if cooldown.0[ability_slot].is_zero() { + cooldown.0[ability_slot] = base_cooldown.0[ability_slot]; commands.spawn(ProjectileBundle::new(ability.to_projectile( *id, position.0, @@ -283,8 +288,8 @@ fn imperative_attack_attack( } } } - Imperative::AttackDirection(ability, direction) => { - let Some(entity) = entity_map.0.get(&id.0) else { + Imperative::AttackDirection(ability_slot, direction) => { + let Ability::Directional(ability) = champion.to_ability(ability_slot) else { *imperative = Imperative::Idle; return; }; @@ -296,8 +301,9 @@ fn imperative_attack_attack( *imperative = Imperative::Idle; return; }; - if cooldown.a_cooldown.is_zero() { - cooldown.a_cooldown = Duration::from_secs_f32(1.5); + let base_cooldown = BaseCooldown::from_champion(*champion); + if cooldown.0[ability_slot].is_zero() { + cooldown.0[ability_slot] = base_cooldown.0[ability_slot]; commands.spawn(ProjectileBundle::new( ability.to_projectile(*id, position.0, direction), )); @@ -435,13 +441,11 @@ fn projectile_despawn( } fn cooldown_decrement(mut cooldowns: Query<&mut Cooldown>, time: Res<Time>) { + let dt = time.delta(); for mut cooldown in cooldowns.iter_mut() { - cooldown.a_cooldown = cooldown.a_cooldown.saturating_sub(time.delta()); - cooldown.q_cooldown = cooldown.q_cooldown.saturating_sub(time.delta()); - cooldown.w_cooldown = cooldown.w_cooldown.saturating_sub(time.delta()); - cooldown.e_cooldown = cooldown.e_cooldown.saturating_sub(time.delta()); - cooldown.d_cooldown = cooldown.d_cooldown.saturating_sub(time.delta()); - cooldown.f_cooldown = cooldown.f_cooldown.saturating_sub(time.delta()); + for ability_slot in AbilitySlot::all() { + cooldown.0[ability_slot] = cooldown.0[ability_slot].saturating_sub(dt); + } } } diff --git a/src/shared/ability.rs b/src/shared/ability.rs index 9639afe..cab7ae6 100644 --- a/src/shared/ability.rs +++ b/src/shared/ability.rs @@ -1,6 +1,8 @@ use crate::shared::player::*; use crate::shared::projectile::*; use crate::shared::*; +use bevy::utils::Duration; +use std::ops::*; #[derive(Copy, Clone, PartialEq, Debug, Deserialize, Serialize)] pub enum Ability { @@ -64,3 +66,54 @@ impl DirectionalAbility { } } } + +#[derive(Debug, Serialize, Deserialize, Clone, Copy, PartialEq, Eq)] +pub enum AbilitySlot { + A, + Q, + W, + E, + R, + F, + G, +} + +impl AbilitySlot { + pub fn to_label(self) -> &'static str { + match self { + AbilitySlot::A => "A", + AbilitySlot::Q => "Q", + AbilitySlot::W => "W", + AbilitySlot::E => "E", + AbilitySlot::R => "R", + AbilitySlot::F => "F", + AbilitySlot::G => "G", + } + } + + pub fn all() -> Vec<Self> { + vec![ + AbilitySlot::A, + AbilitySlot::Q, + AbilitySlot::W, + AbilitySlot::E, + AbilitySlot::R, + AbilitySlot::F, + AbilitySlot::G, + ] + } +} + +impl Index<AbilitySlot> for [Duration; 7] { + type Output = Duration; + + fn index(&self, ability_slot: AbilitySlot) -> &Self::Output { + &self[ability_slot as usize] + } +} + +impl IndexMut<AbilitySlot> for [Duration; 7] { + fn index_mut(&mut self, ability_slot: AbilitySlot) -> &mut Self::Output { + &mut self[ability_slot as usize] + } +} diff --git a/src/shared/champion.rs b/src/shared/champion.rs index 8de12a5..28d1ff2 100644 --- a/src/shared/champion.rs +++ b/src/shared/champion.rs @@ -40,14 +40,14 @@ impl Stats { } impl Champion { - pub fn to_ability(self, attack_key: AttackKey) -> Ability { + pub fn to_ability(self, ability_slot: AbilitySlot) -> Ability { match self { - Champion::Meele => match attack_key { - AttackKey::Q => Ability::Directional(DirectionalAbility::Spear), + Champion::Meele => match ability_slot { + AbilitySlot::Q => Ability::Directional(DirectionalAbility::Spear), _ => Ability::Targeted(TargetedAbility::MeeleAttack), }, - Champion::Ranged => match attack_key { - AttackKey::Q => Ability::Directional(DirectionalAbility::Spear), + Champion::Ranged => match ability_slot { + AbilitySlot::Q => Ability::Directional(DirectionalAbility::Spear), _ => Ability::Targeted(TargetedAbility::RangedAttack), }, } diff --git a/src/shared/cooldown.rs b/src/shared/cooldown.rs index f27d7fc..2d6b6ae 100644 --- a/src/shared/cooldown.rs +++ b/src/shared/cooldown.rs @@ -5,13 +5,12 @@ use serde::Serialize; use std::default::Default; #[derive(Component, Message, Serialize, Deserialize, Clone, Copy, PartialEq, Debug, Default)] -pub struct Cooldown { - pub a_cooldown: Duration, - pub q_cooldown: Duration, - pub w_cooldown: Duration, - pub e_cooldown: Duration, - pub r_cooldown: Duration, - pub d_cooldown: Duration, - pub f_cooldown: Duration, - pub g_cooldown: Duration, +pub struct Cooldown(pub [Duration; 7]); + +pub struct BaseCooldown(pub [Duration; 7]); + +impl BaseCooldown { + pub fn from_champion(_champion: Champion) -> Self { + BaseCooldown([1., 5., 5., 10., 25., 50., 50.].map(Duration::from_secs_f32)) + } } diff --git a/src/shared/imperative.rs b/src/shared/imperative.rs index afdf244..44a0e43 100644 --- a/src/shared/imperative.rs +++ b/src/shared/imperative.rs @@ -8,17 +8,6 @@ use serde::Serialize; pub enum Imperative { Idle, WalkTo(Vec2), - AttackTarget(TargetedAbility, PlayerId), - AttackDirection(DirectionalAbility, Vec2), -} - -#[derive(Resource, Copy, Clone, PartialEq, Debug, Deserialize, Serialize)] -pub enum AttackKey { - A, - Q, - W, - E, - R, - F, - G, + AttackTarget(AbilitySlot, PlayerId), + AttackDirection(AbilitySlot, Vec2), } |