Display lazer mod instead of classic mod

This commit is contained in:
Natsu Kagami 2024-02-14 00:42:40 +01:00
parent 14f17fefd5
commit a79f41a0a7
Signed by: nki
GPG key ID: 55A032EB38B49ADB
5 changed files with 50 additions and 30 deletions

1
Cargo.lock generated
View file

@ -3087,6 +3087,7 @@ dependencies = [
"osuparse", "osuparse",
"rand", "rand",
"regex", "regex",
"reqwest",
"rosu-pp", "rosu-pp",
"rosu-v2", "rosu-v2",
"serde", "serde",

View file

@ -273,12 +273,7 @@ mod scores {
let pw = pp.iter().map(|v| v.len()).max().unwrap_or(2); let pw = pp.iter().map(|v| v.len()).max().unwrap_or(2);
/*mods width*/ /*mods width*/
let mw = plays let mw = plays.iter().map(|v| v.mods.str_len()).max().unwrap().max(4);
.iter()
.map(|v| v.mods.to_string().len())
.max()
.unwrap()
.max(4);
/*beatmap names*/ /*beatmap names*/
let bw = beatmaps.iter().map(|v| v.len()).max().unwrap().max(7); let bw = beatmaps.iter().map(|v| v.len()).max().unwrap().max(7);
/* ranks width */ /* ranks width */
@ -311,16 +306,15 @@ mod scores {
// Each row // Each row
for (id, (play, beatmap)) in plays.iter().zip(beatmaps.iter()).enumerate() { for (id, (play, beatmap)) in plays.iter().zip(beatmaps.iter()).enumerate() {
m.push_line(format!( m.push_line(format!(
"{:>3} | {:>pw$} | {:>8} | {:>rw$} | {:mw$} | {:bw$}", "{:>3} | {:>pw$} | {:>8} | {:>rw$} | {} | {:bw$}",
id + start + 1, id + start + 1,
pp[id], pp[id],
format!("{:.2}%", play.accuracy(self.mode)), format!("{:.2}%", play.accuracy(self.mode)),
ranks[id], ranks[id],
play.mods.to_string(), play.mods.to_string_padded(mw),
beatmap, beatmap,
rw = rw, rw = rw,
pw = pw, pw = pw,
mw = mw,
bw = bw bw = bw
)); ));
} }

View file

@ -461,7 +461,7 @@ async fn show_leaderboard(
/*mods width*/ /*mods width*/
let mdw = scores let mdw = scores
.iter() .iter()
.map(|(_, _, v)| v.mods.to_string().len()) .map(|(_, _, v)| v.mods.str_len())
.max() .max()
.unwrap() .unwrap()
.max(4); .max(4);
@ -514,17 +514,16 @@ async fn show_leaderboard(
)); ));
for (id, (_, member, p)) in scores.iter().enumerate() { for (id, (_, member, p)) in scores.iter().enumerate() {
content.push_line_safe(format!( content.push_line_safe(format!(
"{:>4} | {:>pw$} | {:>mdw$} | {:>rw$} | {:>aw$} | {:>cw$} | {:>mw$} | {:uw$}", "{:>4} | {:>pw$} | {} | {:>rw$} | {:>aw$} | {:>cw$} | {:>mw$} | {:uw$}",
format!("#{}", 1 + id + start), format!("#{}", 1 + id + start),
pp[id], pp[id],
p.mods.to_string(), p.mods.to_string_padded(mdw),
ranks[id], ranks[id],
accuracies[id], accuracies[id],
combos[id], combos[id],
misses[id], misses[id],
member, member,
pw = pw, pw = pw,
mdw = mdw,
rw = rw, rw = rw,
aw = aw, aw = aw,
cw = cw, cw = cw,

View file

@ -1,6 +1,8 @@
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use std::fmt; use std::fmt;
const LAZER_TEXT: &'static str = "";
bitflags::bitflags! { bitflags::bitflags! {
/// The mods available to osu! /// The mods available to osu!
#[derive(std::default::Default, Serialize, Deserialize)] #[derive(std::default::Default, Serialize, Deserialize)]
@ -42,7 +44,7 @@ bitflags::bitflags! {
const MAP_CHANGING = Self::HR.bits | Self::EZ.bits | Self::SPEED_CHANGING.bits; const MAP_CHANGING = Self::HR.bits | Self::EZ.bits | Self::SPEED_CHANGING.bits;
// Made up flags // Made up flags
const CLASSIC = 1 << 59; const LAZER = 1 << 59;
const UNKNOWN = 1 << 60; const UNKNOWN = 1 << 60;
} }
} }
@ -72,10 +74,24 @@ const MODS_WITH_NAMES: &[(Mods, &str)] = &[
(Mods::KEY7, "7K"), (Mods::KEY7, "7K"),
(Mods::KEY8, "8K"), (Mods::KEY8, "8K"),
(Mods::KEY9, "9K"), (Mods::KEY9, "9K"),
(Mods::CLASSIC, "CL"),
(Mods::UNKNOWN, "??"), (Mods::UNKNOWN, "??"),
]; ];
impl Mods {
// Return the string length of the string representation of the mods.
pub fn str_len(&self) -> usize {
let s = format!("{}", self);
s.len() + if s.contains(LAZER_TEXT) { 1 } else { 0 }
}
// Format the mods into a string with padded size.
pub fn to_string_padded(&self, size: usize) -> String {
let s = format!("{}", self);
let real_padded = size - if s.contains(LAZER_TEXT) { 1 } else { 0 };
format!("{:>mw$}", s, mw = real_padded)
}
}
impl std::str::FromStr for Mods { impl std::str::FromStr for Mods {
type Err = String; type Err = String;
fn from_str(mut s: &str) -> Result<Self, Self::Err> { fn from_str(mut s: &str) -> Result<Self, Self::Err> {
@ -112,7 +128,6 @@ impl std::str::FromStr for Mods {
"7K" => res |= Mods::KEY7, "7K" => res |= Mods::KEY7,
"8K" => res |= Mods::KEY8, "8K" => res |= Mods::KEY8,
"9K" => res |= Mods::KEY9, "9K" => res |= Mods::KEY9,
"CL" => res |= Mods::CLASSIC,
"??" => res |= Mods::UNKNOWN, "??" => res |= Mods::UNKNOWN,
v => return Err(format!("{} is not a valid mod", v)), v => return Err(format!("{} is not a valid mod", v)),
} }
@ -127,20 +142,23 @@ impl std::str::FromStr for Mods {
impl fmt::Display for Mods { impl fmt::Display for Mods {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
if self.is_empty() { if !(*self & (Mods::all() ^ Mods::LAZER)).is_empty() {
// Return an empty string
return Ok(());
}
write!(f, "+")?; write!(f, "+")?;
for p in MODS_WITH_NAMES.iter() { for p in MODS_WITH_NAMES.iter() {
if !self.contains(p.0) { if !self.contains(p.0) {
continue; continue;
} }
if p.0 == Mods::DT && self.contains(Mods::NC) { match p.0 {
continue; Mods::DT if self.contains(Mods::NC) => continue,
} Mods::SD if self.contains(Mods::PF) => continue,
_ => (),
};
write!(f, "{}", p.1)?; write!(f, "{}", p.1)?;
} }
}
if self.contains(Mods::LAZER) {
write!(f, "{}", LAZER_TEXT)?;
}
Ok(()) Ok(())
} }
} }

View file

@ -302,12 +302,20 @@ impl From<Mods> for rosu::mods::GameModsIntermode {
res.insert(*m2); res.insert(*m2);
} }
} }
if !value.contains(Mods::LAZER) {
res.insert(GameModIntermode::Classic);
}
res res
} }
} }
impl From<rosu::mods::GameModsIntermode> for Mods { impl From<rosu::mods::GameModsIntermode> for Mods {
fn from(value: rosu_v2::prelude::GameModsIntermode) -> Self { fn from(value: rosu_v2::prelude::GameModsIntermode) -> Self {
let init = if value.contains(GameModIntermode::Classic) {
Mods::NOMOD
} else {
Mods::LAZER
};
value value
.into_iter() .into_iter()
.map(|m| match m { .map(|m| match m {
@ -335,10 +343,10 @@ impl From<rosu::mods::GameModsIntermode> for Mods {
GameModIntermode::SevenKeys => Mods::KEY7, GameModIntermode::SevenKeys => Mods::KEY7,
GameModIntermode::EightKeys => Mods::KEY8, GameModIntermode::EightKeys => Mods::KEY8,
GameModIntermode::NineKeys => Mods::KEY9, GameModIntermode::NineKeys => Mods::KEY9,
GameModIntermode::Classic => Mods::CLASSIC, GameModIntermode::Classic => Mods::NOMOD,
_ => Mods::UNKNOWN, _ => Mods::UNKNOWN,
}) })
.fold(Mods::NOMOD, |a, b| a | b) .fold(init, |a, b| a | b)
// Mods::from_bits_truncate(value.bits() as u64) // Mods::from_bits_truncate(value.bits() as u64)
} }