aboutsummaryrefslogtreecommitdiffstats
path: root/src/server.rs
diff options
context:
space:
mode:
authorLibravatar Alexander Foremny <aforemny@posteo.de>2024-03-15 14:04:17 +0100
committerLibravatar Alexander Foremny <aforemny@posteo.de>2024-03-15 14:25:01 +0100
commitfdee6aa8cf2c51d5004d914458ff661da366e883 (patch)
tree0c022856e64e72a00305e28a684e139696c297ab /src/server.rs
parent1e162629da53373f0e2502014d42c7636412e67e (diff)
feat: add health/ damage
Diffstat (limited to 'src/server.rs')
-rw-r--r--src/server.rs54
1 files changed, 46 insertions, 8 deletions
diff --git a/src/server.rs b/src/server.rs
index c70b39e..fab529f 100644
--- a/src/server.rs
+++ b/src/server.rs
@@ -1,6 +1,7 @@
use crate::protocol::*;
use crate::server::network::*;
use crate::shared::cooldown::*;
+use crate::shared::health::*;
use crate::shared::imperative::*;
use crate::shared::projectile::*;
use crate::shared::*;
@@ -26,14 +27,28 @@ struct ServerPlugin {
pub transport: TransportConfig,
}
+const HEALTH_REGEN_RATE: f32 = 1.;
+
+#[derive(Resource)]
+struct HealthRegenTimer(pub Timer);
+
+impl Default for HealthRegenTimer {
+ fn default() -> Self {
+ HealthRegenTimer(Timer::from_seconds(HEALTH_REGEN_RATE, TimerMode::Repeating))
+ }
+}
+
impl Plugin for ServerPlugin {
fn build(&self, app: &mut App) {
app.insert_resource(EntityMap::default())
+ .insert_resource(HealthRegenTimer::default())
.add_plugins(NetworkPlugin {
transport: self.transport.clone(),
})
.add_systems(Startup, setup)
.add_systems(Update, (connects, disconnects))
+ .add_systems(Update, timers_ticket)
+ .add_systems(Update, health_regen.after(timers_ticket))
.add_systems(
Update,
(
@@ -186,6 +201,7 @@ fn imperative_attack(
projectile: Projectile {
target_player,
source_player: *id,
+ damage: 4.,
},
position: ProjectilePosition(position.0),
replicate: Replicate::default(),
@@ -236,19 +252,29 @@ fn projectile_move(
fn projectile_despawn(
entity_map: Res<EntityMap>,
mut commands: Commands,
- projectile_positions: Query<&ProjectilePosition>,
+ mut healths: Query<&mut Health>,
player_positions: Query<&PlayerPosition>,
+ projectile_positions: Query<&ProjectilePosition>,
projectiles: Query<(Entity, &mut Projectile)>,
) {
for (entity, projectile) in projectiles.iter() {
- if let Some(target_entity) = entity_map.0.get(&projectile.target_player.0) {
- if let Ok(position) = projectile_positions.get(entity) {
- if let Ok(target_position) = player_positions.get(*target_entity) {
- if position.0.distance(target_position.0) <= f32::EPSILON {
- commands.entity(entity).despawn();
- }
- }
+ let Some(target_entity) = entity_map.0.get(&projectile.target_player.0) else {
+ commands.entity(entity).despawn();
+ return;
+ };
+ let Ok(position) = projectile_positions.get(entity) else {
+ commands.entity(entity).despawn();
+ return;
+ };
+ let Ok(target_position) = player_positions.get(*target_entity) else {
+ commands.entity(entity).despawn();
+ return;
+ };
+ if position.0.distance(target_position.0) <= f32::EPSILON {
+ if let Ok(mut health) = healths.get_mut(*target_entity) {
+ health.0 = (health.0 - projectile.damage).max(0.);
}
+ commands.entity(entity).despawn();
}
}
}
@@ -263,3 +289,15 @@ fn cooldown_decrement(mut cooldowns: Query<&mut Cooldown>, time: Res<Time>) {
cooldown.f_cooldown = cooldown.f_cooldown.saturating_sub(time.delta());
}
}
+
+fn timers_ticket(mut health_regen_timer: ResMut<HealthRegenTimer>, time: Res<Time>) {
+ health_regen_timer.0.tick(time.delta());
+}
+
+fn health_regen(health_regen_timer: Res<HealthRegenTimer>, mut healths: Query<&mut Health>) {
+ if health_regen_timer.0.just_finished() {
+ for mut health in healths.iter_mut() {
+ health.0 = (health.0 + 1.).min(MAX_HEALTH);
+ }
+ }
+}