Skip to content

Commit

Permalink
refactor!: add small tick hits (#49)
Browse files Browse the repository at this point in the history
* refactor!: add small tick hits

* doc: add small tick hit explanation
  • Loading branch information
MaxOhn authored Nov 29, 2024
1 parent 76b013a commit cb9877a
Show file tree
Hide file tree
Showing 8 changed files with 142 additions and 79 deletions.
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

0 comments on commit cb9877a

Please sign in to comment.