aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar Alexander Foremny <aforemny@posteo.de>2024-03-17 13:37:58 +0100
committerLibravatar Alexander Foremny <aforemny@posteo.de>2024-03-17 13:40:26 +0100
commit885d0bf2c02fc69fc890765d65067c01741ce47b (patch)
tree3aaee8b6fb196aa94f46d393d41a2bdf99d6942a
parent601474aa84cfc071c724051ac121e3c9cc796577 (diff)
chore: refactor abilities
-rw-r--r--src/client.rs51
-rw-r--r--src/server.rs28
-rw-r--r--src/shared.rs1
-rw-r--r--src/shared/ability.rs65
-rw-r--r--src/shared/champion.rs16
-rw-r--r--src/shared/imperative.rs5
6 files changed, 122 insertions, 44 deletions
diff --git a/src/client.rs b/src/client.rs
index 7f70549..886afd0 100644
--- a/src/client.rs
+++ b/src/client.rs
@@ -1,5 +1,6 @@
use crate::client::network::*;
use crate::protocol::*;
+use crate::shared::ability::*;
use crate::shared::champion::*;
use crate::shared::health::*;
use crate::shared::imperative::*;
@@ -156,31 +157,45 @@ fn buffer_input(
mouse_input: Res<ButtonInput<MouseButton>>,
mut client: ClientMut,
windows: Query<&Window>,
+ champion: Res<MyChampion>,
) {
if mouse_input.just_pressed(MouseButton::Left) {
match attack.0 {
- Some(AttackKey::Q) => {
- let Some(world_position) = cursor_world_position(&windows, &cameras) else {
- return;
- };
- let Some(position) = player_position(&client_id, &players) else {
- return;
- };
- let Some(direction) = (world_position - position.0).try_normalize() else {
- return;
- };
- client.add_input(Inputs::Imperative(Imperative::AttackDirection(
- AttackKey::Q,
- direction,
- )));
- attack.0 = None;
- }
- _ => {
+ Some(attack_key) => match champion.0.to_ability(attack_key) {
+ Ability::Directional(ability) => {
+ let Some(world_position) = cursor_world_position(&windows, &cameras) else {
+ return;
+ };
+ let Some(position) = player_position(&client_id, &players) else {
+ return;
+ };
+ let Some(direction) = (world_position - position.0).try_normalize() else {
+ return;
+ };
+ client.add_input(Inputs::Imperative(Imperative::AttackDirection(
+ ability, direction,
+ )));
+ attack.0 = None;
+ }
+ Ability::Targeted(ability) => {
+ let Some((target_player, _)) =
+ hovered_other_player(&cameras, &client_id, &players, &windows)
+ else {
+ return;
+ };
+ client.add_input(Inputs::Imperative(Imperative::AttackTarget(
+ ability,
+ target_player,
+ )));
+ attack.0 = None;
+ }
+ },
+ None => {
if let Some((target_player, _)) =
hovered_other_player(&cameras, &client_id, &players, &windows)
{
client.add_input(Inputs::Imperative(Imperative::AttackTarget(
- attack.0.unwrap_or(AttackKey::A),
+ TargetedAbility::MeeleAttack,
target_player,
)));
} else {
diff --git a/src/server.rs b/src/server.rs
index b2f22b3..f6cbac3 100644
--- a/src/server.rs
+++ b/src/server.rs
@@ -246,7 +246,7 @@ fn imperative_attack_attack(
) {
for (id, mut imperative) in players.iter_mut() {
match *imperative {
- Imperative::AttackTarget(_, target_player) => {
+ Imperative::AttackTarget(ability, target_player) => {
let Some(entity) = entity_map.0.get(&id.0) else {
*imperative = Imperative::Idle;
return;
@@ -273,26 +273,14 @@ fn imperative_attack_attack(
};
if cooldown.a_cooldown.is_zero() {
cooldown.a_cooldown = Duration::from_secs_f32(1.5);
- let projectile_type = if *champion == Champion::Meele {
- ProjectileType::Instant(InstantProjectile { target_player })
- } else {
- ProjectileType::Targeted(TargetedProjectile {
- target_player,
- position: position.0,
- })
- };
commands.spawn(ProjectileBundle {
- projectile: Projectile {
- source_player: *id,
- damage: 4.,
- type_: projectile_type,
- },
+ projectile: ability.to_projectile(*id, position.0, target_player),
replicate: Replicate::default(),
});
}
}
}
- Imperative::AttackDirection(_, direction) => {
+ Imperative::AttackDirection(ability, direction) => {
let Some(entity) = entity_map.0.get(&id.0) else {
*imperative = Imperative::Idle;
return;
@@ -308,15 +296,7 @@ fn imperative_attack_attack(
if cooldown.a_cooldown.is_zero() {
cooldown.a_cooldown = Duration::from_secs_f32(1.5);
commands.spawn(ProjectileBundle {
- projectile: Projectile {
- source_player: *id,
- damage: 4.,
- type_: ProjectileType::Free(FreeProjectile {
- position: position.0,
- direction,
- starting_position: position.0,
- }),
- },
+ projectile: ability.to_projectile(*id, position.0, direction),
replicate: Replicate::default(),
});
}
diff --git a/src/shared.rs b/src/shared.rs
index a7a2d16..6f01f85 100644
--- a/src/shared.rs
+++ b/src/shared.rs
@@ -9,6 +9,7 @@ use serde::Deserialize;
use serde::Serialize;
use std::default::Default;
+pub mod ability;
pub mod champion;
pub mod cooldown;
pub mod health;
diff --git a/src/shared/ability.rs b/src/shared/ability.rs
new file mode 100644
index 0000000..8ef0c29
--- /dev/null
+++ b/src/shared/ability.rs
@@ -0,0 +1,65 @@
+use crate::shared::projectile::*;
+use crate::shared::*;
+
+#[derive(Copy, Clone, PartialEq, Debug, Deserialize, Serialize)]
+pub enum Ability {
+ Targeted(TargetedAbility),
+ Directional(DirectionalAbility),
+}
+
+#[derive(Copy, Clone, PartialEq, Debug, Deserialize, Serialize)]
+pub enum TargetedAbility {
+ MeeleAttack,
+ RangedAttack,
+}
+
+impl TargetedAbility {
+ pub fn to_projectile(
+ self,
+ source_player: PlayerId,
+ position: Vec2,
+ target_player: PlayerId,
+ ) -> Projectile {
+ match self {
+ TargetedAbility::MeeleAttack => Projectile {
+ type_: ProjectileType::Targeted(TargetedProjectile {
+ target_player,
+ position,
+ }),
+ source_player,
+ damage: 5.,
+ },
+ TargetedAbility::RangedAttack => Projectile {
+ type_: ProjectileType::Instant(InstantProjectile { target_player }),
+ source_player,
+ damage: 6.,
+ },
+ }
+ }
+}
+
+#[derive(Copy, Clone, PartialEq, Debug, Deserialize, Serialize)]
+pub enum DirectionalAbility {
+ Spear,
+}
+
+impl DirectionalAbility {
+ pub fn to_projectile(
+ self,
+ source_player: PlayerId,
+ position: Vec2,
+ direction: Vec2,
+ ) -> Projectile {
+ match self {
+ DirectionalAbility::Spear => Projectile {
+ type_: ProjectileType::Free(FreeProjectile {
+ position,
+ direction,
+ starting_position: position,
+ }),
+ source_player,
+ damage: 15.,
+ },
+ }
+ }
+}
diff --git a/src/shared/champion.rs b/src/shared/champion.rs
index ec27c62..8de12a5 100644
--- a/src/shared/champion.rs
+++ b/src/shared/champion.rs
@@ -1,3 +1,4 @@
+use crate::shared::ability::*;
use crate::shared::*;
use std::str::FromStr;
@@ -37,3 +38,18 @@ impl Stats {
}
}
}
+
+impl Champion {
+ pub fn to_ability(self, attack_key: AttackKey) -> Ability {
+ match self {
+ Champion::Meele => match attack_key {
+ AttackKey::Q => Ability::Directional(DirectionalAbility::Spear),
+ _ => Ability::Targeted(TargetedAbility::MeeleAttack),
+ },
+ Champion::Ranged => match attack_key {
+ AttackKey::Q => Ability::Directional(DirectionalAbility::Spear),
+ _ => Ability::Targeted(TargetedAbility::RangedAttack),
+ },
+ }
+ }
+}
diff --git a/src/shared/imperative.rs b/src/shared/imperative.rs
index 61a4762..886355f 100644
--- a/src/shared/imperative.rs
+++ b/src/shared/imperative.rs
@@ -1,3 +1,4 @@
+use crate::shared::ability::*;
use crate::shared::*;
use serde::Deserialize;
use serde::Serialize;
@@ -6,8 +7,8 @@ use serde::Serialize;
pub enum Imperative {
Idle,
WalkTo(Vec2),
- AttackTarget(AttackKey, PlayerId),
- AttackDirection(AttackKey, Vec2),
+ AttackTarget(TargetedAbility, PlayerId),
+ AttackDirection(DirectionalAbility, Vec2),
}
#[derive(Resource, Copy, Clone, PartialEq, Debug, Deserialize, Serialize)]