diff options
author | Alexander Foremny <aforemny@posteo.de> | 2024-03-21 15:36:05 +0100 |
---|---|---|
committer | Alexander Foremny <aforemny@posteo.de> | 2024-03-22 03:53:08 +0100 |
commit | 91419fb01ef5dcdc06d9f6774d16d3ccca1e4b57 (patch) | |
tree | a302f2ca0d110579f468b2144b81e24f3aa113a3 /src/client.rs | |
parent | 445a51c344ecea346051cf59d03b95c98bb28e75 (diff) |
feat: towers
Diffstat (limited to 'src/client.rs')
-rw-r--r-- | src/client.rs | 123 |
1 files changed, 79 insertions, 44 deletions
diff --git a/src/client.rs b/src/client.rs index ce48b4f..6fa6ff1 100644 --- a/src/client.rs +++ b/src/client.rs @@ -11,8 +11,8 @@ use crate::shared::health_event::*; use crate::shared::imperative::*; use crate::shared::player::*; use crate::shared::projectile::*; +use crate::shared::shape::*; use crate::shared::stats::*; -use crate::shared::*; use bevy::input::keyboard::*; use bevy::input::mouse::MouseButton; use bevy::prelude::*; @@ -24,9 +24,6 @@ use std::net::SocketAddr; mod network; -const PLAYER_HOVER_INDICATOR_RADIUS: f32 = 13.; -const PLAYER_HOVER_RADIUS: f32 = 20.; - pub fn main( server_addr: Option<SocketAddr>, client_id: u64, @@ -193,12 +190,12 @@ fn render_players( mut commands: Commands, mut materials: ResMut<Assets<ColorMaterial>>, mut meshes: ResMut<Assets<Mesh>>, - players: Query<(Entity, &PlayerPosition, &PlayerColor), Added<PlayerId>>, + players: Query<(Entity, &PlayerPosition, &PlayerColor, &Shape), Added<PlayerId>>, ) { - for (entity, position, color) in players.iter() { + for (entity, position, color, shape) in players.iter() { commands.entity(entity).insert(MaterialMesh2dBundle { mesh: Mesh2dHandle(meshes.add(Circle { - radius: PLAYER_RADIUS, + radius: shape.radius, })), material: materials.add(color.0), transform: Transform::from_xyz(position.0.x, position.0.y, 0.), @@ -275,7 +272,7 @@ fn move_players(mut players: Query<(&mut Transform, &PlayerPosition), Changed<Pl } fn buffer_input( - players: Query<(&PlayerId, &PlayerPosition)>, + players: Query<(&PlayerId, &PlayerPosition, &Shape)>, mut attack: ResMut<Attack>, cameras: Query<(&Camera, &GlobalTransform)>, client_id: Res<ClientId>, @@ -303,7 +300,7 @@ fn buffer_input( attack.0 = None; } Ability::Targeted(_) => { - let Some((target_player, _)) = + let Some((target_player, _, _)) = hovered_other_player(&cameras, &client_id, &players, &windows) else { return; @@ -316,7 +313,7 @@ fn buffer_input( } }, None => { - if let Some((target_player, _)) = + if let Some((target_player, _, _)) = hovered_other_player(&cameras, &client_id, &players, &windows) { client.add_input(Inputs::Imperative(Imperative::AttackTarget( @@ -378,15 +375,16 @@ fn choose_attack( fn gizmos_hover_indicator( cameras: Query<(&Camera, &GlobalTransform)>, client_id: Res<ClientId>, - hoverables: Query<(&PlayerId, &PlayerPosition)>, + hoverables: Query<(&PlayerId, &PlayerPosition, &Shape)>, mut gizmos: Gizmos, windows: Query<&Window>, ) { - let Some((_, position)) = hovered_other_player(&cameras, &client_id, &hoverables, &windows) + let Some((_, position, shape)) = + hovered_other_player(&cameras, &client_id, &hoverables, &windows) else { return; }; - gizmos.circle_2d(position.0, PLAYER_HOVER_INDICATOR_RADIUS, Color::GREEN); + gizmos.circle_2d(position.0, shape.radius + 1., Color::GREEN); } fn cursor_world_position( @@ -409,22 +407,22 @@ fn world_to_viewport(cameras: &Query<(&Camera, &GlobalTransform)>, position: Vec fn hovered_other_player( cameras: &Query<(&Camera, &GlobalTransform)>, client_id: &Res<ClientId>, - hoverables: &Query<(&PlayerId, &PlayerPosition)>, + hoverables: &Query<(&PlayerId, &PlayerPosition, &Shape)>, windows: &Query<&Window>, -) -> Option<(PlayerId, PlayerPosition)> { +) -> Option<(PlayerId, PlayerPosition, Shape)> { let Some(world_position) = cursor_world_position(&windows, &cameras) else { return None; }; let mut hovered_player = None; let mut hovered_distance = None; - for (id, position) in hoverables.iter() { + for (id, position, shape) in hoverables.iter() { if id.0 == client_id.0 { continue; } let distance = position.0.distance(world_position); - if distance < PLAYER_HOVER_RADIUS { + if distance < shape.radius + 5. { if hovered_distance.map_or(true, |hovered_distance| distance < hovered_distance) { - hovered_player = Some((*id, *position)); + hovered_player = Some((*id, *position, *shape)); hovered_distance = Some(distance); } } @@ -439,15 +437,25 @@ fn gizmos_attack_indicator( effective_statses: Query<(&PlayerId, &EffectiveStats)>, mut gizmos: Gizmos, player_champions: Query<(&PlayerId, &Champion)>, - player_positions: Query<(&PlayerId, &PlayerPosition)>, + player_positions: Query<(&PlayerId, &PlayerPosition, &Shape)>, + player_entities: Query<(&PlayerId, Entity)>, + pull_targets: Query<(Entity, &PlayerId, &PlayerPosition, &Shape)>, + dash_targets: Query<(Entity, &PlayerId, &PlayerPosition, &Shape)>, + player_shapes: Query<(&PlayerId, &Shape)>, windows: Query<&Window>, ) { + let Some(entity) = player_entity(&client_id, &player_entities) else { + return; + }; let Some(position) = player_position(&client_id, &player_positions) else { return; }; let Some(champion) = player_champion(&client_id, &player_champions) else { return; }; + let Some(shape) = player_shape(&client_id, &player_shapes) else { + return; + }; let Some(ability_slot) = attack.0 else { return; }; @@ -463,13 +471,14 @@ fn gizmos_attack_indicator( let direction = world_position - position.0; match ability { DirectionalAbility::Dash(Dash { max_distance, .. }) => { - let DashCollisionResult { dash_end, .. } = dash_collision( - PlayerId(client_id.0), - position.0, + let Some(DashCollisionResult { dash_end, .. }) = dash_collision( + entity, direction.normalize_or_zero(), max_distance, - &player_positions, - ); + &dash_targets, + ) else { + return; + }; gizmos.arrow_2d(position.0, dash_end, Color::YELLOW); } DirectionalAbility::Flash(Flash { max_distance, .. }) => { @@ -481,27 +490,26 @@ fn gizmos_attack_indicator( ); } DirectionalAbility::Pull(Pull { max_distance, .. }) => { - let Some(PullCollision { + let Some(PullCollisionResult { pull_end, - collision_position, + collision_player_position, .. }) = pull_collision( - PlayerId(client_id.0), - position.0, + entity, direction.normalize_or_zero(), max_distance, - &player_positions, + &pull_targets, ) else { let pull_direction = -max_distance * direction.normalize_or_zero(); let pull_start = position.0 - pull_direction; let pull_end = pull_start - + (pull_direction.length() - 2. * PLAYER_RADIUS) + + (pull_direction.length() - 2. * shape.radius) * pull_direction.normalize_or_zero(); gizmos.arrow_2d(pull_start, pull_end, Color::YELLOW); return; }; - gizmos.arrow_2d(collision_position, pull_end, Color::YELLOW); + gizmos.arrow_2d(collision_player_position.0, pull_end, Color::YELLOW); } DirectionalAbility::Spear(Spear { max_distance, .. }) => { gizmos.arrow_2d( @@ -518,11 +526,23 @@ fn gizmos_attack_indicator( } } +fn player_entity( + client_id: &Res<ClientId>, + players: &Query<(&PlayerId, Entity)>, +) -> Option<Entity> { + for (id, entity) in players.iter() { + if id.0 == client_id.0 { + return Some(entity); + } + } + None +} + fn player_position( client_id: &Res<ClientId>, - players: &Query<(&PlayerId, &PlayerPosition)>, + players: &Query<(&PlayerId, &PlayerPosition, &Shape)>, ) -> Option<PlayerPosition> { - for (id, position) in players.iter() { + for (id, position, _) in players.iter() { if id.0 == client_id.0 { return Some(*position); } @@ -554,12 +574,24 @@ fn player_champion( None } +fn player_shape(client_id: &Res<ClientId>, players: &Query<(&PlayerId, &Shape)>) -> Option<Shape> { + for (id, shape) in players.iter() { + if id.0 == client_id.0 { + return Some(*shape); + } + } + None +} + const HEALTH_OFFSET: f32 = 4.; -fn render_health(players: Query<(&Health, &PlayerPosition, &EffectiveStats)>, mut gizmos: Gizmos) { - for (health, position, effective_stats) in players.iter() { - let start = position.0 + Vec2::new(-PLAYER_RADIUS, PLAYER_RADIUS + HEALTH_OFFSET); - let end = position.0 + Vec2::new(PLAYER_RADIUS, PLAYER_RADIUS + HEALTH_OFFSET); +fn render_health( + players: Query<(&Health, &PlayerPosition, &EffectiveStats, &Shape)>, + mut gizmos: Gizmos, +) { + for (health, position, effective_stats, shape) in players.iter() { + let start = position.0 + Vec2::new(-shape.radius, shape.radius + HEALTH_OFFSET); + let end = position.0 + Vec2::new(shape.radius, shape.radius + HEALTH_OFFSET); let health_start = start; let health_end = start.lerp(end, health.health / effective_stats.0.max_health); let px_per_health = (end.x - start.x) / effective_stats.0.max_health; @@ -570,10 +602,13 @@ fn render_health(players: Query<(&Health, &PlayerPosition, &EffectiveStats)>, mu } } -fn render_buffs(players: Query<(&Buffs, &PlayerPosition)>, mut gizmos: Gizmos) { - for (buffs, position) in players.iter() { - let mut start = - position.0 + Vec2::new(-PLAYER_RADIUS + 1., PLAYER_RADIUS + HEALTH_OFFSET + 2.); +fn render_buffs(players: Query<(&Buffs, &PlayerPosition, &Shape)>, mut gizmos: Gizmos) { + for (buffs, position, player_shape) in players.iter() { + let mut start = position.0 + + Vec2::new( + -player_shape.radius + 1., + player_shape.radius + HEALTH_OFFSET + 2., + ); if buffs.haste.is_some() { gizmos.rect_2d(start, 0., Vec2::new(2., 2.), Color::RED); start = start + Vec2::new(3., 0.); @@ -668,7 +703,7 @@ fn health_indicator_spawn( cameras: Query<(&Camera, &GlobalTransform)>, mut commands: Commands, mut event_reader: EventReader<MessageEvent<HealthChanged>>, - players: Query<(&PlayerId, &PlayerPosition)>, + players: Query<(&PlayerId, &PlayerPosition, &Shape)>, ) { for event in event_reader.read() { let HealthChanged(HealthEvent { @@ -712,9 +747,9 @@ fn health_indicator_spawn( fn any_player_position( player_id: PlayerId, - players: &Query<(&PlayerId, &PlayerPosition)>, + players: &Query<(&PlayerId, &PlayerPosition, &Shape)>, ) -> Option<PlayerPosition> { - for (id, position) in players.iter() { + for (id, position, _) in players.iter() { if *id == player_id { return Some(*position); } |