Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor!: add small tick hits #49

Merged
merged 2 commits into from
Nov 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 16 additions & 7 deletions src/any/performance/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -336,21 +336,30 @@ impl<'map> Performance<'map> {
/// slider heads, ticks, and repeats
pub fn large_tick_hits(self, large_tick_hits: u32) -> Self {
if let Self::Osu(osu) = self {
Self::Osu(osu.n_large_ticks(large_tick_hits))
Self::Osu(osu.large_tick_hits(large_tick_hits))
} else {
self
}
}

/// Specify the amount of hit slider ends.
/// Specify the amount of "small tick" hits.
///
/// Only relevant for osu!standard.
/// Only relevant for osu!standard lazer scores without slider accuracy. In
/// that case, this value is the amount of slider tail hits.
pub fn small_ticks_hits(self, small_tick_hits: u32) -> Self {
if let Self::Osu(osu) = self {
Self::Osu(osu.small_tick_hits(small_tick_hits))
} else {
self
}
}

/// Specify the amount of hit slider ends.
///
/// osu! calls this value "slider tail hits" without the classic
/// mod and "small tick hits" with the classic mod.
pub fn n_slider_ends(self, n_slider_ends: u32) -> Self {
/// Only relevant for osu!standard lazer scores with slider accuracy.
pub fn slider_end_hits(self, slider_end_hits: u32) -> Self {
if let Self::Osu(osu) = self {
Self::Osu(osu.n_slider_ends(n_slider_ends))
Self::Osu(osu.slider_end_hits(slider_end_hits))
} else {
self
}
Expand Down
15 changes: 15 additions & 0 deletions src/any/score_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,16 @@ pub struct ScoreState {
/// slider ticks and repeats
/// - if set on osu!lazer *with* `CL`, this field is the amount of hit
/// slider heads, ticks, and repeats
///
/// Only relevant for osu!lazer.
pub osu_large_tick_hits: u32,
/// "Small ticks" hits for osu!standard.
///
/// These are essentially the slider end hits for lazer scores without
/// slider accuracy.
///
/// Only relevant for osu!lazer.
pub osu_small_tick_hits: u32,
/// Amount of successfully hit slider ends.
///
/// Only relevant for osu!standard in lazer.
Expand All @@ -49,6 +58,7 @@ impl ScoreState {
Self {
max_combo: 0,
osu_large_tick_hits: 0,
osu_small_tick_hits: 0,
slider_end_hits: 0,
n_geki: 0,
n_katu: 0,
Expand Down Expand Up @@ -82,6 +92,7 @@ impl From<ScoreState> for OsuScoreState {
Self {
max_combo: state.max_combo,
large_tick_hits: state.osu_large_tick_hits,
small_tick_hits: state.osu_small_tick_hits,
slider_end_hits: state.slider_end_hits,
n300: state.n300,
n100: state.n100,
Expand Down Expand Up @@ -133,6 +144,7 @@ impl From<OsuScoreState> for ScoreState {
Self {
max_combo: state.max_combo,
osu_large_tick_hits: state.large_tick_hits,
osu_small_tick_hits: state.small_tick_hits,
slider_end_hits: state.slider_end_hits,
n_geki: 0,
n_katu: 0,
Expand All @@ -149,6 +161,7 @@ impl From<TaikoScoreState> for ScoreState {
Self {
max_combo: state.max_combo,
osu_large_tick_hits: 0,
osu_small_tick_hits: 0,
slider_end_hits: 0,
n_geki: 0,
n_katu: 0,
Expand All @@ -165,6 +178,7 @@ impl From<CatchScoreState> for ScoreState {
Self {
max_combo: state.max_combo,
osu_large_tick_hits: 0,
osu_small_tick_hits: 0,
slider_end_hits: 0,
n_geki: 0,
n_katu: state.tiny_droplet_misses,
Expand All @@ -181,6 +195,7 @@ impl From<ManiaScoreState> for ScoreState {
Self {
max_combo: 0,
osu_large_tick_hits: 0,
osu_small_tick_hits: 0,
slider_end_hits: 0,
n_geki: state.n320,
n_katu: state.n200,
Expand Down
1 change: 1 addition & 0 deletions src/catch/performance/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -474,6 +474,7 @@ impl<'map> TryFrom<OsuPerformance<'map>> for CatchPerformance<'map> {
acc,
combo,
large_tick_hits: _,
small_tick_hits: _,
slider_end_hits: _,
n300,
n100,
Expand Down
1 change: 1 addition & 0 deletions src/mania/performance/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -845,6 +845,7 @@ impl<'map> TryFrom<OsuPerformance<'map>> for ManiaPerformance<'map> {
acc,
combo: _,
large_tick_hits: _,
small_tick_hits: _,
slider_end_hits: _,
n300,
n100,
Expand Down
14 changes: 7 additions & 7 deletions src/osu/performance/gradual.rs
Original file line number Diff line number Diff line change
Expand Up @@ -151,30 +151,30 @@ mod tests {
for i in 1.. {
state.misses += 1;

let Some(next_gradual) = gradual.next(state) else {
let Some(next_gradual) = gradual.next(state.clone()) else {
assert_eq!(i, hit_objects_len + 1);
assert!(gradual_2nd.last(state).is_some() || hit_objects_len % 2 == 0);
assert!(gradual_3rd.last(state).is_some() || hit_objects_len % 3 == 0);
assert!(gradual_2nd.last(state.clone()).is_some() || hit_objects_len % 2 == 0);
assert!(gradual_3rd.last(state.clone()).is_some() || hit_objects_len % 3 == 0);
break;
};

if i % 2 == 0 {
let next_gradual_2nd = gradual_2nd.nth(state, 1).unwrap();
let next_gradual_2nd = gradual_2nd.nth(state.clone(), 1).unwrap();
assert_eq!(next_gradual, next_gradual_2nd);
}

if i % 3 == 0 {
let next_gradual_3rd = gradual_3rd.nth(state, 2).unwrap();
let next_gradual_3rd = gradual_3rd.nth(state.clone(), 2).unwrap();
assert_eq!(next_gradual, next_gradual_3rd);
}

let mut regular_calc = OsuPerformance::new(&map)
.difficulty(difficulty.clone())
.passed_objects(i as u32)
.state(state);
.state(state.clone());

let regular_state = regular_calc.generate_state().unwrap();
assert_eq!(state, regular_state);
assert_eq!(state.clone(), regular_state);

let expected = regular_calc.calculate().unwrap();

Expand Down
Loading