diff options
Diffstat (limited to 'src/client.rs')
-rw-r--r-- | src/client.rs | 108 |
1 files changed, 108 insertions, 0 deletions
diff --git a/src/client.rs b/src/client.rs index 1805cae..8220047 100644 --- a/src/client.rs +++ b/src/client.rs @@ -4,6 +4,7 @@ use crate::shared::ability::*; use crate::shared::champion::*; use crate::shared::cooldown::*; use crate::shared::health::*; +use crate::shared::health_event::*; use crate::shared::imperative::*; use crate::shared::projectile::*; use crate::shared::*; @@ -11,6 +12,7 @@ use bevy::input::keyboard::*; use bevy::input::mouse::MouseButton; use bevy::prelude::*; use bevy::sprite::{MaterialMesh2dBundle, Mesh2dHandle}; +use lightyear::client::events::*; use lightyear::client::input::InputSystemSet; use lightyear::prelude::*; use std::net::SocketAddr; @@ -79,6 +81,13 @@ impl Plugin for ClientPlugin { ( (hotbar_hotbar_display, hotbar_hotbar_highlight), hotbar_cooldown, + ( + health_indicator_despawn, + health_indicator_tick, + health_indicator_move_up, + health_indicator_spawn, + ) + .chain(), ), ) .add_systems( @@ -355,6 +364,11 @@ fn cursor_world_position( camera.viewport_to_world_2d(camera_transform, cursor_position) } +fn world_to_viewport(cameras: &Query<(&Camera, &GlobalTransform)>, position: Vec2) -> Option<Vec2> { + let (camera, camera_transform) = cameras.single(); + camera.world_to_viewport(camera_transform, Vec3::new(position.x, position.y, 0.)) +} + fn hovered_other_player( cameras: &Query<(&Camera, &GlobalTransform)>, client_id: &Res<ClientId>, @@ -550,3 +564,97 @@ fn hotbar_hotbar_highlight(attack: Res<Attack>, mut hotbars: Query<(&Hotbar, &mu } } } + +#[derive(Component)] +pub struct HealthIndicator { + position: Vec2, + timer: Timer, +} + +fn health_indicator_spawn( + cameras: Query<(&Camera, &GlobalTransform)>, + mut commands: Commands, + mut event_reader: EventReader<MessageEvent<HealthChanged>>, + players: Query<(&PlayerId, &PlayerPosition)>, +) { + for event in event_reader.read() { + let HealthChanged(HealthEvent { + target_player, + health_gained, + }) = event.message(); + let Some(position) = any_player_position(*target_player, &players) else { + continue; + }; + let health_gained_or_lost = health_gained.abs(); + let Some(mut screen_position) = world_to_viewport(&cameras, position.0) else { + continue; + }; + screen_position += Vec2::new(12.5, -12.5); + commands.spawn(( + TextBundle::from_section( + format!("{health_gained_or_lost}"), + TextStyle { + font_size: 6., + color: Color::RED, + ..Default::default() + }, + ) + .with_style(Style { + position_type: PositionType::Absolute, + top: Val::Px(screen_position.y), + left: Val::Px(screen_position.x), + ..Default::default() + }), + HealthIndicator { + position: position.0, + timer: Timer::from_seconds(1., TimerMode::Once), + }, + )); + } +} + +fn any_player_position( + player_id: PlayerId, + players: &Query<(&PlayerId, &PlayerPosition)>, +) -> Option<PlayerPosition> { + for (id, position) in players.iter() { + if *id == player_id { + return Some(*position); + } + } + None +} + +fn health_indicator_move_up( + cameras: Query<(&Camera, &GlobalTransform)>, + mut health_indicators: Query<(&mut Style, &HealthIndicator)>, +) { + for (mut style, health_indicator) in health_indicators.iter_mut() { + let Some(mut screen_position) = world_to_viewport(&cameras, health_indicator.position) + else { + continue; + }; + screen_position += Vec2::new(12.5, -12.5); + let s = health_indicator.timer.fraction(); + style.top = Val::Px((1. - s) * screen_position.y + s * (screen_position.y - 20.)); + style.left = Val::Px(screen_position.x); + } +} + +fn health_indicator_tick(mut health_indicators: Query<&mut HealthIndicator>, time: Res<Time>) { + for mut health_indicator in health_indicators.iter_mut() { + health_indicator.timer.tick(time.delta()); + } +} + +fn health_indicator_despawn( + health_indicators: Query<(Entity, &HealthIndicator)>, + mut commands: Commands, +) { + for (entity, health_indicator) in health_indicators.iter() { + if !health_indicator.timer.finished() { + continue; + } + commands.entity(entity).despawn(); + } +} |