Skip to content

Commit

Permalink
feat!: pp update (#10)
Browse files Browse the repository at this point in the history
* feat!: pp update

* fix: add small tick hits

* dep: use released rosu-pp
  • Loading branch information
MaxOhn authored Dec 3, 2024
1 parent e6ed5a7 commit 27e8b84
Show file tree
Hide file tree
Showing 13 changed files with 400 additions and 303 deletions.
12 changes: 6 additions & 6 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ crate-type = ["cdylib"]

[dependencies]
pyo3 = { version = "0.22", features = ["extension-module", "macros"] }
rosu-mods = { version = "0.1.0", default-features = false, features = ["serde"] }
rosu-pp = { version = "1.0.0", features = ["sync"] }
serde = "1.0.203"
rosu-mods = { version = "0.2.0", default-features = false, features = ["serde"] }
rosu-pp = { version = "2.0.0", features = ["sync"] }
serde = { version = "1.0.203" }

[profile.release]
lto = true
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ import rosu_pp_py as rosu
# either `path`, `bytes`, or `content` must be specified when parsing a map
map = rosu.Beatmap(path = "/path/to/file.osu")

# Optionally convert to a specific mode
map.convert(rosu.GameMode.Mania)
# Optionally convert to a specific mode for optionally given mods
map.convert(rosu.GameMode.Mania, "6K")

perf = rosu.Performance(
# various kwargs available
Expand Down
154 changes: 150 additions & 4 deletions rosu_pp_py.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -47,13 +47,13 @@ class Beatmap:

def __init__(self, **kwargs) -> None: ...

def convert(self, mode: GameMode) -> None:
def convert(self, mode: GameMode, mods: Optional[GameMods]) -> None:
"""
Convert the beatmap to the specified mode
## Raises
Throws an exception if the specified mode is incompatible with the map's mode
Throws an exception if conversion fails or mods are invalid
"""

@property
Expand Down Expand Up @@ -178,6 +178,11 @@ class Difficulty:
Adjust patterns as if the HR mod is enabled.
Only relevant for osu!catch.
`'lazer': bool`
Whether the calculated attributes belong to an osu!lazer or
osu!stable score.
Defaults to `true`.
"""

def __init__(self, **kwargs) -> None: ...
Expand Down Expand Up @@ -266,6 +271,8 @@ class Difficulty:

def set_hardrock_offsets(self, hardrock_offsets: Optional[bool]) -> None: ...

def set_lazer(self, lazer: Optional[bool]) -> None: ...

class Performance:
"""
Builder for a performance calculation
Expand Down Expand Up @@ -337,12 +344,39 @@ class Performance:
Adjust patterns as if the HR mod is enabled.
Only relevant for osu!catch.
`'lazer': bool`
Whether the calculated attributes belong to an osu!lazer or
osu!stable score.
Defaults to `true`.
`'accuracy': float`
Set the accuracy between `0.0` and `100.0`.
`'combo': int`
Specify the max combo of the play.
Irrelevant for osu!mania.
`'large_tick_hits': int`
The amount of "large tick" hits.
Only relevant for osu!standard.
The meaning depends on the kind of score:
- if set on osu!stable, this value is irrelevant and can be `0`
- if set on osu!lazer *without* `CL`, this value is the amount of hit
slider ticks and repeats
- if set on osu!lazer *with* `CL`, this value is the amount of hit
slider heads, ticks, and repeats
`'small_tick_hits': int`
The amount of "small tick" hits.
These are essentially the slider end hits for lazer scores without
slider accuracy.
Only relevant for osu!standard.
`'slider_end_hits': int`
The amount of slider end hits.
Only relevant for osu!standard in lazer.
`'n_geki': int`
Specify the amount of gekis of a play.
Expand Down Expand Up @@ -445,10 +479,18 @@ class Performance:

def set_hardrock_offsets(self, hardrock_offsets: Optional[bool]) -> None: ...

def set_lazer(self, lazer: Optional[bool]) -> None: ...

def set_accuracy(self, accuracy: Optional[float]) -> None: ...

def set_combo(self, combo: Optional[int]) -> None: ...

def set_large_tick_hits(self, n_large_ticks: Optional[int]) -> None: ...

def set_small_tick_hits(self, n_large_ticks: Optional[int]) -> None: ...

def set_slider_end_hits(self, n_slider_ends: Optional[int]) -> None: ...

def set_n_geki(self, n_geki: Optional[int]) -> None: ...

def set_n_katu(self, n_katu: Optional[int]) -> None: ...
Expand Down Expand Up @@ -667,6 +709,33 @@ class ScoreState:
Irrelevant for osu!mania.
"""

osu_large_tick_hits: int
"""
"Large tick" hits for osu!standard.
The meaning depends on the kind of score:
- if set on osu!stable, this field is irrelevant and can be `0`
- if set on osu!lazer *without* `CL`, this field is the amount of hit
slider ticks and repeats
- if set on osu!lazer *with* `CL`, this field is the amount of hit
slider heads, ticks, and repeats
"""

osu_small_tick_hits: int
"""
"Small tick" hits for osu!standard.
These are essentially the slider end hits for lazer scores without
slider accuracy.
"""

slider_end_hits: int
"""
Amount of successfully hit slider ends.
Only relevant for osu!standard in lazer.
"""

n_geki: int
"""
Amount of current gekis (n320 for osu!mania).
Expand Down Expand Up @@ -760,6 +829,22 @@ class DifficultyAttributes:
Only available for osu!.
"""

@property
def aim_difficult_strain_count(self) -> Optional[float]:
"""
Weighted sum of aim strains.
Only available for osu!.
"""

@property
def speed_difficult_strain_count(self) -> Optional[float]:
"""
Weighted sum of speed strains.
Only available for osu!.
"""

@property
def od(self) -> Optional[float]:
"""
Expand Down Expand Up @@ -792,6 +877,21 @@ class DifficultyAttributes:
Only available for osu!.
"""

@property
def n_large_ticks(self) -> Optional[int]:
"""
The amount of "large tick" hits.
Only relevant for osu!standard.
The meaning depends on the kind of score:
- if set on osu!stable, this value is irrelevant and can be `0`
- if set on osu!lazer *without* `CL`, this value is the amount of hit
slider ticks and repeats
- if set on osu!lazer *with* `CL`, this value is the amount of hit
slider heads, ticks, and repeats
"""

@property
def n_spinners(self) -> Optional[int]:
"""
Expand All @@ -808,6 +908,14 @@ class DifficultyAttributes:
Only available for osu!taiko.
"""

@property
def single_color_stamina(self) -> Optional[float]:
"""
The difficulty of the single color stamina skill.
Only available for osu!taiko.
"""

@property
def rhythm(self) -> Optional[float]:
"""
Expand Down Expand Up @@ -864,6 +972,14 @@ class DifficultyAttributes:
Only available for osu!mania.
"""

@property
def n_hold_notes(self) -> Optional[int]:
"""
The amount of hold notes in the map.
Only available for osu!mania.
"""

@property
def ar(self) -> Optional[float]:
"""
Expand All @@ -873,13 +989,21 @@ class DifficultyAttributes:
"""

@property
def hit_window(self) -> Optional[float]:
def great_hit_window(self) -> Optional[float]:
"""
The perceived hit window for an n300 inclusive of rate-adjusting mods (DT/HT/etc)
Only available for osu!taiko and osu!mania.
"""

@property
def ok_hit_window(self) -> Optional[float]:
"""
The perceived hit window for an n100 inclusive of rate-adjusting mods (DT/HT/etc)
Only available for osu!taiko.
"""

@property
def max_combo(self) -> int:
"""
Expand Down Expand Up @@ -943,6 +1067,14 @@ class PerformanceAttributes:
Only available for osu! and osu!taiko.
"""

@property
def estimated_unstable_rate(self) -> Optional[float]:
"""
Upper bound on the player's tap deviation.
Only *optionally* available for osu!taiko.
"""

@property
def pp_difficulty(self) -> Optional[float]:
"""
Expand Down Expand Up @@ -1019,6 +1151,12 @@ class Strains:
Strain peaks of the stamina skill in osu!taiko.
"""

@property
def single_color_stamina(self) -> Optional[List[float]]:
"""
Strain peaks of the single color stamina skill in osu!taiko.
"""

@property
def movement(self) -> Optional[List[float]]:
"""
Expand Down Expand Up @@ -1058,7 +1196,15 @@ class BeatmapAttributes:
"""

@property
def od_hitwindow(self) -> float:
def od_great_hitwindow(self) -> float:
"""
Hit window for overall difficulty i.e. time to hit a 300 ("Great") in milliseconds.
"""

@property
def od_ok_hitwindow(self) -> float:
"""
Hit window for overall difficulty i.e. time to hit a 100 ("Ok") in milliseconds.
Not available for osu!mania.
"""
9 changes: 6 additions & 3 deletions src/attributes/beatmap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,8 @@ define_class! {
pub hp: f64!,
pub clock_rate: f64!,
pub ar_hitwindow: f64!,
pub od_hitwindow: f64!,
pub od_great_hitwindow: f64!,
pub od_ok_hitwindow: f64?,
}
}

Expand All @@ -244,7 +245,8 @@ impl From<BeatmapAttributes> for PyBeatmapAttributes {
hit_windows:
HitWindows {
ar: ar_hitwindow,
od: od_hitwindow,
od_great: od_great_hitwindow,
od_ok: od_ok_hitwindow,
},
} = attrs;

Expand All @@ -255,7 +257,8 @@ impl From<BeatmapAttributes> for PyBeatmapAttributes {
hp,
clock_rate,
ar_hitwindow,
od_hitwindow,
od_great_hitwindow,
od_ok_hitwindow,
}
}
}
Loading

0 comments on commit 27e8b84

Please sign in to comment.