diff options
author | Alexander Foremny <aforemny@posteo.de> | 2024-03-15 14:04:17 +0100 |
---|---|---|
committer | Alexander Foremny <aforemny@posteo.de> | 2024-03-15 14:25:01 +0100 |
commit | fdee6aa8cf2c51d5004d914458ff661da366e883 (patch) | |
tree | 0c022856e64e72a00305e28a684e139696c297ab /src/server.rs | |
parent | 1e162629da53373f0e2502014d42c7636412e67e (diff) |
feat: add health/ damage
Diffstat (limited to 'src/server.rs')
-rw-r--r-- | src/server.rs | 54 |
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); + } + } +} |