From b11db0bf854fd5bdf4559495257a66518f532c21 Mon Sep 17 00:00:00 2001 From: Logan Allred Date: Sun, 16 Jun 2024 08:59:13 -0600 Subject: [PATCH 1/5] Add basic enemy colors to minimap Fixes #584 The playable player is still always blue, but all other players are assigned a color based on their player number. --- crates/controller/src/hud/minimap/fill.rs | 57 +++++++++++++++++++---- 1 file changed, 48 insertions(+), 9 deletions(-) diff --git a/crates/controller/src/hud/minimap/fill.rs b/crates/controller/src/hud/minimap/fill.rs index ec59f672..3c76d4b4 100644 --- a/crates/controller/src/hud/minimap/fill.rs +++ b/crates/controller/src/hud/minimap/fill.rs @@ -1,3 +1,6 @@ +use super::draw::DrawingParam; +use crate::ray::ScreenRay; +use ahash::AHashMap; use bevy::{ecs::system::SystemParam, prelude::*}; use de_core::{ gamestate::GameState, gconfig::GameConfig, objects::ObjectTypeComponent, @@ -6,22 +9,56 @@ use de_core::{ use de_map::size::MapBounds; use de_objects::SolidObjects; use de_terrain::TerrainCollider; -use de_types::projection::ToFlat; +use de_types::{objects::*, projection::ToFlat}; use parry2d::{ bounding_volume::Aabb, math::Point, query::{Ray, RayCast}, }; -use super::draw::DrawingParam; -use crate::ray::ScreenRay; - const TERRAIN_COLOR: Color = Color::rgb(0.61, 0.46, 0.32); const PLAYER_COLOR: Color = Color::rgb(0.1, 0.1, 0.9); -const ENEMY_COLOR: Color = Color::rgb(0.9, 0.1, 0.1); +const ENEMY_COLORS: [Color; 4] = [ + Color::rgb(0.1, 0.9, 0.1), + Color::rgb(0.9, 0.1, 0.1), + Color::rgb(0.9, 0.9, 0.1), + Color::rgb(0.1, 0.9, 0.9), +]; const MIN_ENTITY_SIZE: Vec2 = Vec2::splat(0.02); const CAMERA_COLOR: Color = Color::rgb(0.9, 0.9, 0.9); +#[derive(Resource, Debug)] +struct PlayerColors { + player: (Color, AHashMap), + enemies: [(Color, AHashMap); 4], +} + +impl Default for PlayerColors { + fn default() -> Self { + Self { + player: derive_colors(PLAYER_COLOR), + enemies: [ + derive_colors(ENEMY_COLORS[0]), + derive_colors(ENEMY_COLORS[1]), + derive_colors(ENEMY_COLORS[2]), + derive_colors(ENEMY_COLORS[3]), + ], + } + } +} + +fn derive_colors(base_color: Color) -> (Color, AHashMap) { + let mut unit_color = base_color.clone(); + unit_color.set_s(base_color.s() - 0.3); + let mut object_colors = AHashMap::new(); + object_colors.insert( + ObjectType::Active(ActiveObjectType::Unit(UnitType::Attacker)), + unit_color, + ); + + (base_color, object_colors) +} + pub(super) struct FillPlugin; impl Plugin for FillPlugin { @@ -75,21 +112,23 @@ fn draw_entities_system( ui_coords: UiCoords, solids: SolidObjects, game: Res, + colors: Local, entities: Query<(&Transform, &PlayerComponent, &ObjectTypeComponent)>, ) { let mut drawing = drawing.drawing(); for (transform, &player, &object_type) in entities.iter() { let minimap_position = ui_coords.flat_to_rel(transform.translation.to_flat()); - let color = if game.locals().is_playable(*player) { - PLAYER_COLOR + let (player_color, object_colors) = if game.locals().is_playable(*player) { + &colors.player } else { - ENEMY_COLOR + &colors.enemies[(player.to_num() - 1) as usize] }; + let color = object_colors.get(&*object_type).unwrap_or(&player_color); let radius = solids.get(*object_type).ichnography().radius(); let rect_size = MIN_ENTITY_SIZE.max(ui_coords.size_to_rel(Vec2::splat(radius))); - drawing.rect(minimap_position, rect_size, color); + drawing.rect(minimap_position, rect_size, *color); } } From 5da5e6434dc904a5abdb40f3fdb0909170fb3f92 Mon Sep 17 00:00:00 2001 From: Logan Allred Date: Tue, 18 Jun 2024 08:23:36 -0600 Subject: [PATCH 2/5] set array sizes to MAX_PLAYERS refactor PlayerColors to be easier to re-use --- crates/controller/src/hud/minimap/fill.rs | 59 ++++++++++++----------- 1 file changed, 32 insertions(+), 27 deletions(-) diff --git a/crates/controller/src/hud/minimap/fill.rs b/crates/controller/src/hud/minimap/fill.rs index 3c76d4b4..314bccfb 100644 --- a/crates/controller/src/hud/minimap/fill.rs +++ b/crates/controller/src/hud/minimap/fill.rs @@ -3,13 +3,13 @@ use crate::ray::ScreenRay; use ahash::AHashMap; use bevy::{ecs::system::SystemParam, prelude::*}; use de_core::{ - gamestate::GameState, gconfig::GameConfig, objects::ObjectTypeComponent, - player::PlayerComponent, schedule::PostMovement, + gamestate::GameState, objects::ObjectTypeComponent, player::PlayerComponent, + schedule::PostMovement, }; use de_map::size::MapBounds; use de_objects::SolidObjects; use de_terrain::TerrainCollider; -use de_types::{objects::*, projection::ToFlat}; +use de_types::{objects::*, player::Player, projection::ToFlat}; use parry2d::{ bounding_volume::Aabb, math::Point, @@ -17,37 +17,48 @@ use parry2d::{ }; const TERRAIN_COLOR: Color = Color::rgb(0.61, 0.46, 0.32); -const PLAYER_COLOR: Color = Color::rgb(0.1, 0.1, 0.9); -const ENEMY_COLORS: [Color; 4] = [ +const PLAYER_COLORS: [Color; Player::MAX_PLAYERS] = [ + Color::rgb(0.1, 0.1, 0.9), Color::rgb(0.1, 0.9, 0.1), Color::rgb(0.9, 0.1, 0.1), Color::rgb(0.9, 0.9, 0.1), - Color::rgb(0.1, 0.9, 0.9), ]; const MIN_ENTITY_SIZE: Vec2 = Vec2::splat(0.02); const CAMERA_COLOR: Color = Color::rgb(0.9, 0.9, 0.9); #[derive(Resource, Debug)] struct PlayerColors { - player: (Color, AHashMap), - enemies: [(Color, AHashMap); 4], + player_colors: [Color; Player::MAX_PLAYERS], + object_colors: [AHashMap; Player::MAX_PLAYERS], } - -impl Default for PlayerColors { - fn default() -> Self { +impl PlayerColors { + fn new(colors: [Color; Player::MAX_PLAYERS]) -> Self { Self { - player: derive_colors(PLAYER_COLOR), - enemies: [ - derive_colors(ENEMY_COLORS[0]), - derive_colors(ENEMY_COLORS[1]), - derive_colors(ENEMY_COLORS[2]), - derive_colors(ENEMY_COLORS[3]), + player_colors: colors, + object_colors: [ + derive_colors(colors[0]), + derive_colors(colors[1]), + derive_colors(colors[2]), + derive_colors(colors[3]), ], } } + + fn get_color(&self, player: Player, object_type: ObjectType) -> Color { + let player_idx: usize = (player.to_num() - 1) as usize; + let default_color: Color = self.player_colors[player_idx]; + let object_color = self.object_colors[player_idx].get(&object_type); + + *object_color.unwrap_or(&default_color) + } +} +impl Default for PlayerColors { + fn default() -> Self { + Self::new(PLAYER_COLORS) + } } -fn derive_colors(base_color: Color) -> (Color, AHashMap) { +fn derive_colors(base_color: Color) -> AHashMap { let mut unit_color = base_color.clone(); unit_color.set_s(base_color.s() - 0.3); let mut object_colors = AHashMap::new(); @@ -56,7 +67,7 @@ fn derive_colors(base_color: Color) -> (Color, AHashMap) { unit_color, ); - (base_color, object_colors) + object_colors } pub(super) struct FillPlugin; @@ -111,7 +122,6 @@ fn draw_entities_system( mut drawing: DrawingParam, ui_coords: UiCoords, solids: SolidObjects, - game: Res, colors: Local, entities: Query<(&Transform, &PlayerComponent, &ObjectTypeComponent)>, ) { @@ -119,16 +129,11 @@ fn draw_entities_system( for (transform, &player, &object_type) in entities.iter() { let minimap_position = ui_coords.flat_to_rel(transform.translation.to_flat()); - let (player_color, object_colors) = if game.locals().is_playable(*player) { - &colors.player - } else { - &colors.enemies[(player.to_num() - 1) as usize] - }; - let color = object_colors.get(&*object_type).unwrap_or(&player_color); + let color = colors.get_color(*player, *object_type); let radius = solids.get(*object_type).ichnography().radius(); let rect_size = MIN_ENTITY_SIZE.max(ui_coords.size_to_rel(Vec2::splat(radius))); - drawing.rect(minimap_position, rect_size, *color); + drawing.rect(minimap_position, rect_size, color); } } From e27e60f0560098bbe10285f3fdce0d1febea0d75 Mon Sep 17 00:00:00 2001 From: Logan Allred Date: Wed, 19 Jun 2024 11:10:54 -0600 Subject: [PATCH 3/5] refactor PlayerColors to be a simpler tuple struct implenting the suggested improvements made the tuple struct faster than the hashmap lookup --- crates/controller/src/hud/minimap/fill.rs | 54 ++++++----------------- 1 file changed, 14 insertions(+), 40 deletions(-) diff --git a/crates/controller/src/hud/minimap/fill.rs b/crates/controller/src/hud/minimap/fill.rs index 314bccfb..60a48cfd 100644 --- a/crates/controller/src/hud/minimap/fill.rs +++ b/crates/controller/src/hud/minimap/fill.rs @@ -1,6 +1,5 @@ use super::draw::DrawingParam; use crate::ray::ScreenRay; -use ahash::AHashMap; use bevy::{ecs::system::SystemParam, prelude::*}; use de_core::{ gamestate::GameState, objects::ObjectTypeComponent, player::PlayerComponent, @@ -27,49 +26,23 @@ const MIN_ENTITY_SIZE: Vec2 = Vec2::splat(0.02); const CAMERA_COLOR: Color = Color::rgb(0.9, 0.9, 0.9); #[derive(Resource, Debug)] -struct PlayerColors { - player_colors: [Color; Player::MAX_PLAYERS], - object_colors: [AHashMap; Player::MAX_PLAYERS], -} +struct PlayerColors([Color; Player::MAX_PLAYERS]); impl PlayerColors { - fn new(colors: [Color; Player::MAX_PLAYERS]) -> Self { - Self { - player_colors: colors, - object_colors: [ - derive_colors(colors[0]), - derive_colors(colors[1]), - derive_colors(colors[2]), - derive_colors(colors[3]), - ], - } - } - - fn get_color(&self, player: Player, object_type: ObjectType) -> Color { + fn get_color(&self, player: Player, object_type: ActiveObjectType) -> Color { let player_idx: usize = (player.to_num() - 1) as usize; - let default_color: Color = self.player_colors[player_idx]; - let object_color = self.object_colors[player_idx].get(&object_type); - - *object_color.unwrap_or(&default_color) + let player_color = self.0[player_idx].as_hsla(); + match object_type { + ActiveObjectType::Building(_) => player_color, + ActiveObjectType::Unit(_) => player_color.with_s(0.7 * player_color.s()), + } } } impl Default for PlayerColors { fn default() -> Self { - Self::new(PLAYER_COLORS) + Self(PLAYER_COLORS) } } -fn derive_colors(base_color: Color) -> AHashMap { - let mut unit_color = base_color.clone(); - unit_color.set_s(base_color.s() - 0.3); - let mut object_colors = AHashMap::new(); - object_colors.insert( - ObjectType::Active(ActiveObjectType::Unit(UnitType::Attacker)), - unit_color, - ); - - object_colors -} - pub(super) struct FillPlugin; impl Plugin for FillPlugin { @@ -129,11 +102,12 @@ fn draw_entities_system( for (transform, &player, &object_type) in entities.iter() { let minimap_position = ui_coords.flat_to_rel(transform.translation.to_flat()); - let color = colors.get_color(*player, *object_type); - - let radius = solids.get(*object_type).ichnography().radius(); - let rect_size = MIN_ENTITY_SIZE.max(ui_coords.size_to_rel(Vec2::splat(radius))); - drawing.rect(minimap_position, rect_size, color); + if let ObjectType::Active(active_object) = *object_type { + let color = colors.get_color(*player, active_object); + let radius = solids.get(*object_type).ichnography().radius(); + let rect_size = MIN_ENTITY_SIZE.max(ui_coords.size_to_rel(Vec2::splat(radius))); + drawing.rect(minimap_position, rect_size, color); + } } } From 5a00e27865392fcf92deefc2a1e47b90ffde4b4e Mon Sep 17 00:00:00 2001 From: Logan Allred Date: Thu, 20 Jun 2024 03:28:48 -0600 Subject: [PATCH 4/5] fix formatting --- crates/controller/src/hud/minimap/fill.rs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/crates/controller/src/hud/minimap/fill.rs b/crates/controller/src/hud/minimap/fill.rs index 60a48cfd..2678eb78 100644 --- a/crates/controller/src/hud/minimap/fill.rs +++ b/crates/controller/src/hud/minimap/fill.rs @@ -1,5 +1,3 @@ -use super::draw::DrawingParam; -use crate::ray::ScreenRay; use bevy::{ecs::system::SystemParam, prelude::*}; use de_core::{ gamestate::GameState, objects::ObjectTypeComponent, player::PlayerComponent, @@ -15,6 +13,9 @@ use parry2d::{ query::{Ray, RayCast}, }; +use super::draw::DrawingParam; +use crate::ray::ScreenRay; + const TERRAIN_COLOR: Color = Color::rgb(0.61, 0.46, 0.32); const PLAYER_COLORS: [Color; Player::MAX_PLAYERS] = [ Color::rgb(0.1, 0.1, 0.9), @@ -27,6 +28,7 @@ const CAMERA_COLOR: Color = Color::rgb(0.9, 0.9, 0.9); #[derive(Resource, Debug)] struct PlayerColors([Color; Player::MAX_PLAYERS]); + impl PlayerColors { fn get_color(&self, player: Player, object_type: ActiveObjectType) -> Color { let player_idx: usize = (player.to_num() - 1) as usize; @@ -37,6 +39,7 @@ impl PlayerColors { } } } + impl Default for PlayerColors { fn default() -> Self { Self(PLAYER_COLORS) From 7e68d01f2d27e3bf09523e21a8776d541b1f6161 Mon Sep 17 00:00:00 2001 From: Logan Allred Date: Thu, 20 Jun 2024 03:46:00 -0600 Subject: [PATCH 5/5] use type is now more specific --- crates/controller/src/hud/minimap/fill.rs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/crates/controller/src/hud/minimap/fill.rs b/crates/controller/src/hud/minimap/fill.rs index 2678eb78..80421d1f 100644 --- a/crates/controller/src/hud/minimap/fill.rs +++ b/crates/controller/src/hud/minimap/fill.rs @@ -6,7 +6,11 @@ use de_core::{ use de_map::size::MapBounds; use de_objects::SolidObjects; use de_terrain::TerrainCollider; -use de_types::{objects::*, player::Player, projection::ToFlat}; +use de_types::{ + objects::{ActiveObjectType, ObjectType}, + player::Player, + projection::ToFlat, +}; use parry2d::{ bounding_volume::Aabb, math::Point,