diff --git a/src/menu.rs b/src/menu.rs index bce6828..16e238e 100644 --- a/src/menu.rs +++ b/src/menu.rs @@ -37,6 +37,7 @@ impl Plugin for MenuPlugin { #[derive(Resource)] pub struct DeathScreenInputDelayTimer(pub Timer); #[derive(Component)] pub struct MenuElement; #[derive(Component)] pub struct MenuTopLevel; +#[derive(Component)] pub struct MenuAchievements; #[derive(Component)] pub struct DeathScreenElement; #[derive(Component)] pub struct DeathText; #[derive(Event)] pub struct UpdateMenuEvent; @@ -181,6 +182,52 @@ pub fn setup( }, )); }); + + let style_achievement_header = TextStyle { + font: font_handle.clone(), + font_size: settings.font_size_achievement_header, + color: settings.hud_color_achievement_header, + ..default() + }; + let style_achievement = TextStyle { + font: font_handle.clone(), + font_size: settings.font_size_achievement, + color: settings.hud_color_achievement, + ..default() + }; + + commands.spawn(( + MenuElement, + NodeBundle { + style: Style { + width: Val::Percent(100.0), + height: Val::Percent(100.0), + align_items: AlignItems::Start, + justify_content: JustifyContent::Start, + ..default() + }, + visibility: Visibility::Hidden, + ..default() + }, + )).with_children(|builder| { + let mut sections = vec![ + TextSection::new("Achievements\n", style_achievement_header) + ]; + sections.extend(Vec::from_iter((0..var::ACHIEVEMENT_COUNT).map(|_| + TextSection::new("", style_achievement.clone()) + ))); + builder.spawn(( + MenuAchievements, + TextBundle { + text: Text { + sections, + justify: JustifyText::Left, + ..default() + }, + ..default() + }, + )); + }); } pub fn show_deathscreen( @@ -250,7 +297,9 @@ pub struct MenuState { pub fn update_menu( mut q_text: Query<&mut Text, With>, + mut q_achievement_text: Query<&mut Text, (With, Without)>, mut q_vis: Query<&mut Visibility, With>, + achievement_tracker: Res, menustate: Res, settings: Res, ) { @@ -260,6 +309,19 @@ pub fn update_menu( fn bool2string(boolean: bool) -> String { if boolean { "On" } else { "Off" }.to_string() } + + let bools = achievement_tracker.to_bool_vec(); + let rendered = achievement_tracker.to_textsections(); + if let Ok(mut text) = q_achievement_text.get_single_mut() { + for i in 0..text.sections.len() - 1 { + text.sections[i + 1].style.color = if bools[i] { + settings.hud_color_achievement_accomplished + } else { + settings.hud_color_achievement + }; + text.sections[i + 1].value = rendered[i].clone(); + } + } if let Ok(mut text) = q_text.get_single_mut() { for i in 0..text.sections.len() { if menustate.cursor == i { diff --git a/src/var.rs b/src/var.rs index 4ae5861..d3075ab 100644 --- a/src/var.rs +++ b/src/var.rs @@ -20,6 +20,7 @@ use toml_edit::DocumentMut; use std::env; use std::fs; +pub const ACHIEVEMENT_COUNT: usize = 5; pub const SCOPE_SEPARATOR: &str = "$"; pub const TOKEN_EQUALS: &str = "=="; @@ -56,6 +57,8 @@ pub struct Settings { pub font_size_deathtext: f32, pub font_size_deathsubtext: f32, pub font_size_deathpoem: f32, + pub font_size_achievement: f32, + pub font_size_achievement_header: f32, pub hud_color: Color, pub hud_color_fps: Color, pub hud_color_console: Color, @@ -66,6 +69,9 @@ pub struct Settings { pub hud_color_choices: Color, pub hud_color_speedometer: Color, pub hud_color_deathpoem: Color, + pub hud_color_achievement: Color, + pub hud_color_achievement_header: Color, + pub hud_color_achievement_accomplished: Color, pub chat_speed: f32, pub flashlight_active: bool, pub hud_active: bool, @@ -169,6 +175,8 @@ impl Default for Settings { font_size_deathtext: 64.0, font_size_deathsubtext: 32.0, font_size_deathpoem: 18.0, + font_size_achievement: 24.0, + font_size_achievement_header: 32.0, hud_color: Color::hex("#BE1251").unwrap(), hud_color_fps: Color::hex("#181818").unwrap(), hud_color_console: Color::hex("#BE1251").unwrap(), @@ -179,6 +187,9 @@ impl Default for Settings { hud_color_choices: Color::hex("#727272").unwrap(), hud_color_speedometer: Color::hex("#BE1251").unwrap(), hud_color_deathpoem: Color::hex("#CC2200").unwrap(), + hud_color_achievement: Color::hex("#666666").unwrap(), + hud_color_achievement_accomplished: Color::hex("#F0D50C").unwrap(), + hud_color_achievement_header: Color::hex("#BE1251").unwrap(), chat_speed: DEFAULT_CHAT_SPEED * if dev_mode { 2.5 } else { 1.0 }, flashlight_active: false, hud_active: true, @@ -302,6 +313,37 @@ pub struct AchievementTracker { pub all_people: HashSet, } +impl AchievementTracker { + pub fn to_bool_vec(&self) -> Vec { + vec![ + self.repair_suit, + self.drink_a_pizza, + self.ride_every_vehicle, + self.talk_to_everyone, + self.in_jupiters_shadow, + ] + } + pub fn to_textsections(&self) -> Vec { + fn bool2string(boolean: bool) -> String { + if boolean { "achieved" } else { "not achieved" }.to_string() + } + vec![ + format!("Repair Your Suit ({})\n", + bool2string(self.repair_suit)), + format!("Consume A Pizza ({})\n", + bool2string(self.drink_a_pizza)), + format!("Ride Every Vehicle ({}/{})\n", + self.vehicles_ridden.len(), + self.all_vehicles.len()), + format!("Talk To Everyone ({}/{})\n", + self.people_talked_to.len(), + self.all_people.len()), + format!("Let Jupiter Eclipse The Sun ({})\n", + bool2string(self.in_jupiters_shadow)), + ] + } +} + #[derive(Resource, Deserialize, Debug, Default)] #[serde(default)] pub struct Preferences {