* Add new API property backing for tiered rank
* Slightly refactor `ProfileValueDisplay` for direct access to things that will need direct access
* Extract separate component for global rank display
* Add tiered colours for global rank
* Add Github link button to wiki overlay header
* Localize jump link string
* Mark ILinkHandler dependency as nullable
* Make the button actually look like it does on the website
* Use existing web string instead of inventing a new one
* Bind value change callback more reliably
---------
Co-authored-by: Bartłomiej Dach <dach.bartlomiej@gmail.com>
This was primarily written to fix
https://github.com/ppy/osu/issues/35538, but also incidentally targets
some other scenarios, such as:
- When switching from artist filtering to title filtering, selection
sometimes would stay at the group under which the selection's artist
was filed, rather than moving to the group under which the selection's
title is filed (in other words, the group that *the selection is
currently under*).
- When simply assigning a beatmap to a collection such that it would
be moved out of the current group, the selection will now follow to
the new collection's group rather than staying at its previous
position.
Whether this is desired is highly likely to be extremely situational,
but I don't want to introduce complications unless it's absolutely
necessary.
This has a significant performance overhead because
`CheckModelEquality()` isn't free, but it doesn't seem horrible in
profiling.
Calling `HandleItemActivated()` rather than its intended 'parent method'
of `Activate()` meant that selection state was not correctly
invalidated:
819da1bc38/osu.Game/Graphics/Carousel/Carousel.cs (L157)
which in turn meant that carousel item Y positions would not be
recalculated correctly after the group was expanded, which meant that
the items would become
- visible,
- stuck to the bottom of the expanded group,
- one on top of another.
Which is not something that's going to perform well.
Certified OOP moment.
Fell out when attempting
https://github.com/ppy/osu-server-spectator/pull/346.
Functionally, if a true non-`HubException` is produced via an invocation
of a spectator server hub method, this doesn't really do much - the
error will still log as 'unobserved' due to the default handler, it will
still show up on sentry, etc. The only difference is that it'll get
handled via the continuation installed in `FireAndForget()` rather than
the `TaskScheduler.UnobservedTaskException` event.
The only real case where this is relevant is when the server throws
`HubException`s, which will now instead bubble up to a more
human-readable form. Which is relevant to the aforementioned PR because
that one makes any hub method potentially throw a `HubException` if the
client version is too old.
Obviously this does nothing for the existing old clients.
* Apply some renames & drawable names for visualiser
Optional but really helps me make heads of tails as to what anything is
here.
Like really, multiple variations of `footerContent` inside a
`ScreenFooter` class, with zero elaboration that it's really content to
do with *overlays*...
* Fix screen footer overlay content being pushed to right during fade-out
- Closes https://github.com/ppy/osu/issues/35203
- Supersedes / closes https://github.com/ppy/osu/pull/35468
Closes https://github.com/ppy/osu/issues/35003.
Bit dodgy to use `CurrentSelectionItem` for this. Ideally I would use
the global `Beatmap.IsDefault`, but I kind of don't want to violate the
rule that `BeatmapCarousel` shouldn't have direct access to the global
beatmap. And this seems to work, so... maybe fine to use until it
doesn't?
This is actually possible in current usages if you e.g. toggle "use
original metadata" on/off which will change the width of the underlying
sprite texts. Or by setting window size. Pick your poison.
Instead of truncating.
Addresses https://github.com/ppy/osu/discussions/35404.
The one "tiny" problem is that the "click to search" functionality of
these texts is maybe a bit worse now, because the clickable target is
now the full width of the wedge rather than autosized to the text.
Salvaging this is *maybe* possible, but *definitely* annoying, so I'd
rather not frontload it.
Is this lazy? Sure it is. Friends and blocks do the same thing, though,
and I'm not overthinking this any more than I already have.
Being smarter here would likely mean being more invasive with respect to
listening in on all outgoing API requests and silently updating
favourites on that basis. Which is "smart" but also complicated.
Something I've asked to be done for a long time. Relevant because I've
complained about this on every addition of a new piece of user-local
state: friends, blocks, and now favourite beatmaps.
It's just so messy managing all this inside `APIAccess` next to
everything else, IMO.
The "partial" leaderboard logic in `SoloGameplayLeaderboardProvider`
always assumed the online fetch would request 50 scores, which is no
longer the case after https://github.com/ppy/osu/pull/33100.
This is a set of model changes which is supposed to facilitate support
for custom sample sets to the beatmap editor that is on par with stable.
It is the minimal set of changes. Because of this, it can probably be
considered "ugly" or however else you want to put it - but before you
say that, I want to try and pre-empt that criticism by explaining where
the problems lie.
Problem #1: duality in sample models
---
There is currently a weird duality of what a `HitObject`'s samples will
be.
- If an object has just been placed in the editor, and not saved /
decoded yet, it will use `HitSampleInfo`.
- If an object has already been encoded to the beatmap at least once, it
will use `ConvertHitObjectParser.LegacyHitSampleInfo`.
As long as that state of affairs remains, `HitSampleInfo` must be able
to represent anything that `LegacyHitSampleInfo` can, if feature parity
is to be achieved.
Problem 2: The 0 & 1 sample banks
---
Custom sample banks of 2 and above are a pretty clean affair. They map to
a suffix on the sample filename, and said samples are allowed to be
looked up from the beatmap skin. `Suffix` already exists in
`HitSampleInfo`.
However, the 1 custom sample bank is evil. It uses *non-suffixed*
samples, *allows lookups from the beatmap skins*, contrary to no bank /
bank 0, which *also* uses non-suffixed samples, but *doesn't* allow them
to be looked up from the beatmap skin.
This is why `HitSampleInfo.UseBeatmapSamples` has been called to
existence - without it there is no way to represent the ability of using
or not using the beatmap skin assets.
As has been stated previously in discussions about this feature, it's
both a *mapping* and a *skinning* concern.
There are many things you could do about either of these problems, but I
am pretty sure tackling either one is going to take *many* more lines of
code than this commit does. Which is why this is the starting point of
negotiation.
The equality check that was supposed to replace the read of
`CurrentSelectionItem` showed up as a hotspot in profiling.
The selection updating code looks a little stupid after this, but all in
the name of performance...
Beatmap panels can be visible for very brief instants.
`PanelSetBackground` has a backstop to prevent expensive background
loads which is based on the position of the panel relative to centre of
screen.
However, retrieving the working beatmap that *precedes* any of that
expensive background load logic, is *also* expensive, and *always* runs
even if a panel is visible on screen for only a brief second. Therefore,
by moving some of that background load delay towards delaying retrieving
the working beatmap, we can save on doing even more work, which has
beneficial implications for performance.
I had previously made it invariant in
https://github.com/ppy/osu/pull/32837, and in another instance of past
me being an asshole, I can't actually find the reasoning for this at
this time.
That said, you'd be excused for thinking "why does this matter"? Well,
this will fix https://github.com/ppy/osu/issues/35381, because that
failure only occurs when the user's culture is set to one that doesn't
use a decimal point (.) but rather a decimal comma (,). This messes with
framework, which uses the *current* culture to check for decimal
separator rather than invariant:
d3226a7842/osu.Framework/Graphics/UserInterface/TextBox.cs (L106-L111)
An alternative would be to change framework instead to always accept the
invariant decimal separator.
God I hate this culture crap.
* SSV2 : Replace Mark as Played with Remove from Played if already played
* Remove checks of BeatmapInfo.LastPlayed for DateTimeOffset.MinValue
* Make FooterButtonOptions use a RealmLive<BeatmapInfo> and act on review comments
* FIXUP: Detach BeatmapInfo before passing it to FooterButtonOptions.Popover
---------
Co-authored-by: Bartłomiej Dach <dach.bartlomiej@gmail.com>
* Remove unnecessary information from matchmaking beatmap panel
* Move avatar overlay inside card for better layout
* Allow higher jumping when jumping in succession
* Exclude player panel avatars from masking
* Adjust player panel animations a bit further
* Add avatar-only display mode
* Fix round warmup test not working
* Remove dead test scenes
* Fix edge case where users are added to not-yet-loaded card
* Decouple `PlayerPanel` from `UserPanel`
* Fix remaining test failure (and rename test to match new naming)
From local testing on release build (such that online beatmaps are
accessible) with a large database it seems that maybe this'll help with
recurrent complaints of 'stutters'.
Co-authored-by: Dean Herbert <pe@ppy.sh>
I'm not exactly sure on the reproduction scenario here, but I have had
switching ruleset with converts disabled crash on me a few times
today. It appears to happen sometimes when after the switch the expanded
group no longer exists in the set mapping, because a filter just ran and
removed that group from set of possible groups because there'd be no
beatmaps under it.
I tried to manufacture a quick test but it's not a quick one to test
because filtering intereference is required to reproduce, I think.
I will try again on request but I mostly just want to get this fix out
ASAP before I finish up for the day.
Because the detached store exists and has a chance to actually
semi-reliably intercept a beatmap update operation, I decided to try
this. It still uses a bit of a heuristic in that it checks for
transactions that delete and insert one beatmap each, but probably the
best effort thus far?
Notably old song select that was already doing the same thing locally to
itself got a bit broken by this, but with some tweaking that *looks* to
be more or less harmless I managed to get it unbroken. I'm not too
concerned about old song select, mind, mostly just want to keep it
*vaguely* working if I can help it.
Addresses https://github.com/ppy/osu/discussions/35182.
The source as it is would have you believe that this is correct and
intentional but I'm not so sure about that. For one thing, I
cross-checked stable, and sure, missing tiny droplets does change the
state to fail over there. For another, the guard in master at
5e642cbce7/osu.Game.Rulesets.Catch/UI/Catcher.cs (L250)
is very suspicious, given that it is dead in cause of tiny droplets
because of a preceding guard:
5e642cbce7/osu.Game.Rulesets.Catch/UI/Catcher.cs (L227-L228)
Looking into blame, the tiny droplet guard originates at
e7f1f0f38b, wherein it looks to have been
aimed at handling *hyperdash* state specifically. Later, the logic has
been moved around and around like five times; at
7069cef9ce, the catcher animation logic
was added *below* the hyperdash-aimed guard without the comment being
updated in any way; 5a5c956ced moved the
logic from `CatcherArea` to `Catcher`, while simultaneously changing
the inline comment to no longer mention hyperdashing; and finally,
1d669cf65e added specific testing of tiny
droplets not changing catcher animation state, which I wager to be
back-engineered from the implementation as-it-was rather than
supported by any actual ground truth.
For additional reference:
- catcher animation logic in stable is at 67795dba3c/osu!/GameModes/Play/Rulesets/Fruits/RulesetFruits.cs#L411-L463
- hyperdash application logic in stable is at 67795dba3c/osu!/GameModes/Play/Rulesets/Fruits/RulesetFruits.cs#L165-L171
Addresses https://github.com/ppy/osu/issues/33443, maybe.
I considered adding tests but they'd likely be janky and take a long
time to write, so decided against until there's a demand for it.
Closes https://github.com/ppy/osu/issues/34062.
The root cause of the issue is that `OnEntering()` calls
`onArrivingAtScreen()`, which calls `ensureGlobalBeatmapValid()`, which
would call `checkBeatmapValidForSelection()` with a `FilterCriteria`
instance retrieved from the `FilterControl`.
The problem with that is at the time that this call chain is happening,
`FilterControl` is not yet loaded, which means in particular that it has
not bound itself to the config bindable, as that happens on
`LoadComplete()`:
bff07010d1/osu.Game/Screens/SelectV2/FilterControl.cs (L198)
To resolve this, retrieve the bindable in `SongSelect` itself, which
ensures it is valid for reading at the time the above call chain
happens.
Because it is 99% sure that doing so will fail and spam the user with
"this beatmap doesn't match the online version" notifications, and
because the map status is "locally modified", they should be pretty
aware of that already. This fixes the primary mode of the failure that
https://github.com/ppy/osu/pull/35173 was attempting to hack around.
This will have regressed somewhere around the time that BSS went live,
because at that point the editor stopped resetting online IDs for
beatmaps that got locally modified, making the `beatmapId <= 0` guards
no longer prevent attempts of submission.
A relatively recent regression. It's maybe not a huge one, in that it
probably doesn't matter all that much, but it is somewhat important to
keep the "locally modified" status of the set for as long as possible.
One reason for that is that keeping the "locally modified" status will
pull up a dialog when the user attempts to update the beatmap, warning
them that they will lose their local changes - this dialog will not show
if the online lookup flow is allowed to overwrite the map status with
something else.
Closes https://github.com/ppy/osu/issues/34810.
The reason why I touched it in this direction and not the other is only
because the standalone panel positioning of the button was touched last
in 92ed964627, thus I changed the set
panel to match that.
Closes https://github.com/ppy/osu/issues/35113.
Regressed in dfed564bda - setting
`Carousel.CurrentSelection` was not all that
`requestRecommendedSelection()` was doing there...
A potential point of discussion is whether this global beatmap switch
should be debounced or instant. I'm not sure I have a particularly
well-formed opinion on that. One argument in favour of not debouncing is
that if you look closely at the left side of the screen while the
debounce is in progress, you can still sort of see the broken behaviour
happen - it just doesn't stay there forever.
Thankfully `ensureGlobalBeatmapValid()` being called in every scenario
on screen suspension prevented this bug from being any worse than it is
right now.
Closes https://github.com/ppy/osu/issues/35010.
The issue here does not reproduce consistently, and is more or less
random in presentation. That said, using a large enough realm database
more or less ensures that the issue will present itself (in testing on a
large realm db, the failure rate is around ~50%).
This actually regressed in https://github.com/ppy/osu/pull/34842. The
core failure in this case is here:
fd412618db/osu.Game/Screens/SelectV2/BeatmapCarousel.cs (L161)
The `CheckModelEquality()` call above is comparing two `BeatmapInfo`s,
but a84c364e44 changed the
`BeatmapInfo`-comparing path of `CheckModelEquality()` to use
`GroupedBeatmap` instead. Due to this, `CheckModelEquality()` falls back
to reference equality comparison for `BeatmapInfo`s. When that reference
comparison fails, the carousel stops detecting that the current
selection was deleted from under it correctly, and therefore the
proximity-based selection logic never runs.
Due to the human-obvious mechanism of failure and relatively easy
manual reproduction I've decided not to try and add tests for this,
as they are likely to take a long time to write due to the mechanism
of failure being incorrect use of reference equality specifically. That
said, I can try on request.
Probably closes https://github.com/ppy/osu/issues/35138. I'm not sure. I
only got the issue to reproduce once, on dev, using a very large
archive that was uploading really slowly, and then never again.
The working theory is that basically handling of `progressSampleChannel`
is quite dodgy and it could possibly, in circumstances unknown, be
allowed to play forevermore after transitioning to failed / canceled
state. Success state does not get this treatment because it has special
logic to set progress to 1.
11 is excessive. There can ever be at most 9 of these panels, ever,
because there are at most 9 possible letter grades at this time (F, D,
C, B, A, S, S+, SS, SS+).
Easiest way to make this work without rewriting the layout logic.
I think it makes sense to have the button still exist there but not be
usable on certain screens.
* Change maximum UR estimation + buff rhythm
* Penalty for classic ezhd
* Buff mono bonus to counterbalance logic fix
* New miss penalty + slightly nerf length bonus
* Adjust rhythm values
* Adjust penalty and buff high SR acc
* Exclude HDFL from hidden reading penalties
* Make comment a lil nicer
---------
Co-authored-by: James Wilson <tsunyoku@gmail.com>
Closes https://github.com/ppy/osu/issues/34959.
`ArgonCounterTextComponent` is pretty terrible and prevents being able
to fix the issue easily. The core issue is that this is the first
instance of the component's usage where the label text can be longer
than the counter in the X dimension, so the total width of any counter
is equal to max(label width, counter width), and the label will be
aligned to the left of that width, while the counter will be aligned to
the right of that width.
The fix sort of relies on the fact that I don't expect *any* consumer of
`ArgonCounterTextComponent` that meaningfully uses the wireframe digits
to want the non-wireframe digits to be aligned to the *left* rather than
the right. It's not what I'd expect any segmented display to work.
(There are usages that specify `TopLeft` anchor, but they usually
display the same number of wireframe and non-wireframe digits, so for
them it doesn't really matter if the digits are left-aligned to the
wireframes or not.)
I'm doing this silently to see if any users complain without being told
about the change. Without this, when holding left arrow for short
bursts, precisely *one* beatmap change happens before actual key repeat
kicks in, which feels really weird (updates the leaderboard / background
unexpectedly).
This is the simplest way to resolve the issue, so if users aren't
offended by it I think we should commit to it.
Personally it's still fast enough to not annoy me at all.
I can't see how this can happen in a normal flow, so just doing it as a
safety measure. Pointed out in https://github.com/ppy/osu/issues/34940
but likely due to a third party fuck being loaded.
Regressed with https://github.com/ppy/osu-server-spectator/pull/311.
As it turns out, the method not just resets ready states but also the
beatmap availabilities. So we have to send it again here.
I have a feeling this is also broken in standard multiplayer in some way
or another.
d4b357dfa0 contains a sneaky regression.
The previous code read:
if (CurrentSelection != null && CheckModelEquality(beatmap, CurrentSelection))
RequestSelection(matchingNewBeatmap);
and the new one reads:
if (CurrentSelection is GroupedBeatmap currentBeatmapUnderGrouping)
{
var candidateSelection = currentBeatmapUnderGrouping with { Beatmap = beatmap };
if (CheckModelEquality(candidateSelection, CurrentSelection))
RequestSelection(candidateSelection);
}
The point is that we want to reselect `matchingNewBeatmap` here, not the
old selection. The `CheckModelEquality()` check's purpose is to check
whether *the current selection needs updating*.
I'm not sure why tests just wonderfully passed despite this, but my
suspicion is that it was because of accidental copying of realm guids
that obscured this problem.
This should better account for scenarios where user FPS is below 60 fps.
Previously the debounce would unexpectedly be longer than usual for low
FPS scenarios.
* Prevent Taiko difficulty crash if a map only contains 0-strains
* Add second check for safety
This is accessing a different array of strains. I'd rather be safe than sorry.
* Add guard in PP too
* Make `MarginOfError` a const
This isn't a super common mod compared to every other one on the list, it's probably not worth the storage (and memory in case of stable) implications. We can look at revisiting this once we have actual spinner difficulty considerations
This is probably where things get a little controversial.
There are some song select flows wherein song select just wants to
ensure sanity by authoritatively setting the global beatmap. The goal is
to change the beatmap immediately and instantly. Therefore it should
kind of be the carousel's job to figure out its grouping complications.
To that end, `CurrentSelection` is made virtual, and overridden in
`BeatmapCarousel` to perform a sort of reconciliation logic. If an
external component sets `CurrentSelection` to a `BeatmapInfo`, one of
the two following things happen:
- Nothing, if the current `GroupedBeatmap` is already a copy of the
beatmap that needs to be selected, or
- The carousel looks at its items, finds any first copy which matches
the beatmap that the external consumer wanted selected, and changes
selection to that instead.
Basically, `BeatmapCarousel.CurrentSelection`, which is
magic-object-typed, can no longer use `BeatmapInfo` directly, it now
must also use `GroupedBeatmap`.
This spills out all the way into song select because of beatmap
selection flows that require hookup from song select.
This bypasses the immediate first issue of not being able to display
multiple instances of a beatmap on the carousel because of model
equality being baked into the structure. It inevitably poses a bunch of
*other* problems, but it's a start.
Previously CompositeDrawable.CheckChildrenLife() would be run before lifetimeManager.Update() which lead to the new drawables being inserted into the container but not being made alive immediately, leading to the drawable not becoming visibile until the next update loop.
This stems from me looking into `TestSceneFailAnimation` failures
(https://github.com/ppy/osu/runs/48663953318). As it turns out, I should
not have been mad by CI, and rather should have been mad at myself for
failing to read.
`FailedAtJudgement` in fact does not mean "this judgement, and only this
judgement, triggered failure". If any further judgements occur
post-fail, they will also have `FailedAtJudgement` set to true. It is
essentially a *dump* of the state of `HealthProcessor.Failed` prior to
applying the judgement.
ec21685c25/osu.Game/Rulesets/Scoring/HealthProcessor.cs (L49-L57)
Because of this, reverting several judgements which occur post-fail
could lead to failed state reverting earlier than intended, and thus
potentially trigger a second fail, thus tripping the `Player` assertion.
The `BeatmapDifficultyCache` handles mod changes, so handling locally is
unnecessary. By handling locally, it creates a visual issue when
adjusting mods often. Test using Ctrl +/- at song select and observing
that without this change, the star rating will flicker back to the
default due to the local re-fetch.
Due to `Perform` being used from a BDL method in conjunction with
`Success` (which is scheduled to the *update* thread), there was a
chance that the order of execution would be not quite as intended.
To rectify, let's not use `Success` and just continue with synchronous
flow.
uh, yeah, I accidentally flipped the colors around in the UpdateColour() method (which I should've probably make private or protected), and it's the reason why the logo overall looked dimmer than it should've
anyhow, this should *probably* look a bit better, don't have any means to test it yet though
Note that this does not handle sizing/scaling changes applied directly
to `Playfield`, but it handles any changes within the layers inside
`PlayfieldAdjustmentContainer`.
Because the flashlight is made to be scaled by playfield, there are
constant scale factors applied somewhere in the
`PlayfieldAdjustmentContainer` which needs to be reflected in the
flashlight size to keep the size the same.
The factor is specifically 1.6x, computed in {Osu,Catch}PlayfieldAdjustmentContainer.ScalingContainer`.
More generally, I've deduced these factors by logging the difference
between the `flashlightSize` before and after b78abe2f.
Closes https://github.com/ppy/osu/issues/34731.
The failure scenario here is as follows:
- User holds down left mouse button for >200ms to reveal the background.
- User presses down another mouse button and releases it in <200ms.
- User releases left mouse button. Song select does not return.
The timing here is key because what is happening here is that the second
mouse button press is overwriting the `revealingBackground` scheduled
delegate. Releasing that same mouse button within 200ms leads to that
scheduled delegate being cancelled and cleared, and thus the release of
left mouse wrongly decides there is nothing left to do.
One thing I'm not entirely sure about is the release behaviour even with
this change; as things stand, the first release of any mouse button will
bring song select back, even if it was not the button that was initially
held down to reveal the background. That's probably easily fixed if
deemed required, but I'm most interested in fixing the bad breakage.
Addresses https://github.com/ppy/osu/discussions/34705, I suppose.
The cagey tone of that statement is because this change merely papers
over the issue. The issue in question for the user that reported this is
that they have a bunch of very old beatmaps, whose md5 hashes do not
match the online hashes, that need updating. The submission/rank date
population was running every single time for these, and failing every
time, because there is really not much useful that the lookup *can* do.
Because mappers have made `OnlineID` essentially useless for determining
the provenance of a beatmap due to reusing them to "fix" beatmap
submission failures, online IDs have been explicitly disallowed from use
in any sort of beatmap lookup flow. The only things that are allowed to
be used are: md5 of the beatmap, and filename as a fallback for very old
beatmaps / beatmap packs.
If the user has local beatmaps with md5 not matching online, chances are
that any metadata lookups are likely to fail or return bogus data. At
that point my personal feeling is that backpopulation flows should leave
such beatmaps well alone and the user should just go update the beatmap
themselves.
I am aware that updating 124 individual beatmap sets would - in the
current state of things - would probably be a ridiculously onerous thing
to do, and that people have been asking multiple times for a facility to
update all local beatmaps at once, but that discussion is out of scope
at this stage.
Only seems to reproduce in gameplay for whatever reason. Can't justify
spending time to chase down why really because the previous code looked
obviously wrong on closer inspection anyway (`rightLayer` has transforms
applied to it on collapse/expand).
Probably closes https://github.com/ppy/osu/issues/34716
Can't see any other cause, can reproduce the issue on master using
manual db modifications via realm studio and it is not a consistent
reproduction, so seems like an open-and-shut lack of refresh.
* Test theory crafting
* Place in more appropriate place
* fix a bit better
* Move things around
* Reduce diff
---------
Co-authored-by: StanR <hi@stanr.info>
* New acc curve
* Penalise rhythm difficulty based on unstable rate
* Rename mono acc stuff for more clarity
* Fix nullable
* Rename stuff
* Get actual estimation for SS unstable rate
* Double space my bad
---------
Co-authored-by: James Wilson <tsunyoku@gmail.com>
* Calculate consistency factor from object strains
* Use `totalDifficultHits` in performance calc
---------
Co-authored-by: James Wilson <tsunyoku@gmail.com>
* Rebalance aim and speed
* Rebalance star rating
* Attempt further speed balancing
* More balancing
* More balancing
* Buff aim a bit
* More speed balancing
* Global rebalance
* Speed balancing
* Global rebalancing
* More speed balancing
* Buff aim
* MORE BALANCING
* Revert "Rebalance star rating"
This reverts commit f48c7445e12174c65b74edfef863cb3ae3cc29ff.
* Decouple velocity change bonus from wide angle bonus
* Replace sin with smoothstep
* Set multiplier back to 0.75
---------
Co-authored-by: James Wilson <tsunyoku@gmail.com>
* Change pp summing and adjust multipliers
* Add back convert consideration for hidden
* And the other one whoops
---------
Co-authored-by: StanR <hi@stanr.info>
* Reduce combo scaling for osu!catch
This is a conservative reduction, a middle point between the current
scaling and the CSR proposals.
* Reduce osu!catch combo scaling further
0.45 makes little difference so let's reduce it a bit more.
---------
Co-authored-by: James Wilson <tsunyoku@gmail.com>
* initial commit
* changed HD curve
* removed AR variable
* update for new rework
* nerf HD acc bonus for AR>10
* add another HD nerf for AR>10
* Update OsuDifficultyCalculator.cs
* fix speed part being missing
* Update OsuDifficultyCalculator.cs
* rework to difficulty-based high AR nerf
* move TC back to perfcalc
* fix nvicka
* fix comment
* use utils function instead of manual one
* Clean up
* Use "visibility" term instead
* Store `mechanicalDifficultyRating` field
* Rename `isFullyHidden` to `isAlwaysPartiallyVisible` and clarify intent
* Remove redundant comment
* Add `calculateDifficultyRating` method
---------
Co-authored-by: James Wilson <tsunyoku@gmail.com>
* Buff precision difficulty rating in osu!
* Fix position repetition calculation
* Fix aim evaluator crashing, move small circle bonus calculation, adjust the curve slightly
* Refactor
* Fix code quality
* Semicolon
* Apply small circle bonus to speed too
* Fix formatting
---------
Co-authored-by: James Wilson <tsunyoku@gmail.com>
* implement stuff
* fix basic issues
* rework calculations
* sanity check
* don't use score based misscount if no scorev1 present
* Update OsuPerformanceCalculator.cs
* update misscount diff attribute names
* add raw score misscount attribute
* introduce more reasonable high bound for misscount
* code quality changes
* Fix osu!catch SR buzz slider detection (#32412)
* Use `normalized_hitobject_radius` during osu!catch buzz slider detection
Currently the algorithm considers some buzz sliders as standstills when
in reality they require movement. This happens because `HalfCatcherWidth`
isn't normalized while `exactDistanceMoved` is, leading to an inaccurate
comparison.
`normalized_hitobject_radius` is the normalized value of `HalfCatcherWidth`
and replacing one with the other fixes the problem.
* Rename `normalized_hitobject_radius` to `normalized_half_catcher_width`
The current name is confusing because hit objects have no radius in the
context of osu!catch difficulty calculation. The new name conveys the
actual purpose of the value.
* Only set `normalized_half_catcher_width` in `CatchDifficultyHitObject`
Prevents potential bugs if the value were to be changed in one of the
classes but not in both.
* Use `CatchDifficultyHitObject.NORMALIZED_HALF_CATCHER_WIDTH` directly
Requested during code review.
---------
Co-authored-by: James Wilson <tsunyoku@gmail.com>
* Move osu!catch movement diffcalc to an evaluator (#32655)
* Move osu!catch movement state into `CatchDifficultyHitObject`
In order to port `Movement` to an evaluator, the state has to be either
moved elsewhere or calculated inside the evaluator. The latter requires
backtracking for every hit object, which in the worst case is continued
until the beginning of the map is reached. Limiting backtracking can
lead to difficulty value changes.
Thus, the first option was chosen for its simplicity.
* Move osu!catch movement difficulty calculation to an evaluator
Makes the code more in line with the other game modes.
* Add documentation for `CatchDifficultyHitObject` fields
---------
Co-authored-by: James Wilson <tsunyoku@gmail.com>
* Move all score-independent bonuses into star rating (#31351)
* basis refactor to allow for more complex SR calculations
* move all possible bonuses into star rating
* decrease star rating scaling to account for overall gains
* add extra FL guard for safety
* move star rating multiplier into a constant
* Reorganise some things
* Add HD and SO to difficulty adjustment mods
* Move non-legacy mod multipliers back to PP
* Some merge fixes
* Fix application of flashlight rating multiplier
* Fix Hidden bonuses being applied when Blinds mod is in use
* Move part of speed OD scaling into difficulty
* Move length bonus back to PP
* Remove blinds special case
* Revert star rating multiplier decrease
* More balancing
---------
Co-authored-by: StanR <hi@stanr.info>
* Add diffcalc considerations for Magnetised mod (#33004)
* Add diffcalc considerations for Magnetised mod
* Make speed reduction scale with power too
* cleaning up
* Update OsuPerformanceCalculator.cs
* Update OsuPerformanceCalculator.cs
* add new check to avoid overestimation
* fix code style
* fix nvicka
* add database attributes
* Refactor
* Rename `Working` to `WorkingBeatmap`
* Remove redundant condition
* Remove useless variable
* Remove `get` wording
* Rename `calculateScoreAtCombo`
* Remove redundant operator
* Add comments to explain how score-based miss count derivations work
* Remove redundant `decimal` calculations
* use static method to improve performance
* move stuff around for readability
* move logic into helper class
* fix the bug
* Delete OsuLegacyScoreProcessor.cs
* Delete ILegacyScoreProcessor.cs
* revert static method for multiplier
* use only basic combo score attribute
* Clean-up
* Remove unused param
* Update osu.Game.Rulesets.Osu/Difficulty/OsuPerformanceCalculator.cs
Co-authored-by: StanR <castl@inbox.ru>
* rename variables
* Add `LegacyScoreUtils`
* Add fail safe
* Move `countMiss`
* Better explain `CalculateRelevantScoreComboPerObject`
* Add `OsuLegacyScoreMissCalculator`
* Move `CalculateScoreAtCombo` and `CalculateRelevantScoreComboPerObject`
* Remove unused variables
* Move `GetLegacyScoreMultiplier`
* Add `estimated` wording
---------
Co-authored-by: wulpine <wulpine@proton.me>
Co-authored-by: James Wilson <tsunyoku@gmail.com>
Co-authored-by: StanR <hi@stanr.info>
Co-authored-by: StanR <castl@inbox.ru>
* scale misscount by proportion of difficult sliders
* cap sliderbreak count at count100 + count50
* use countMiss instead of effectiveMissCount as the base for sliderbreaks
* make code inspector happy + cleanup
* refactor to remove unnecesary calculation and need for new tuple
* scale sliderbreaks with combo
* use aimNoSliders for sliderbreak factor
* code cleanup
* make inspect code happy
* use diffcalcutils
* fix errors (oops)
* scaling changes
* fix div by zeros
* Fix compilation error
* Add online attributes for new difficulty attributes
* Formatting
* Rebase fixes
* Make `CountTopWeightedSliders` to remove weird protected `SliderStrains` list
* Prevent top weighted slider factor from being Infinity
---------
Co-authored-by: tsunyoku <tsunyoku@gmail.com>
* basis refactor to allow for more complex SR calculations
* move all possible bonuses into star rating
* decrease star rating scaling to account for overall gains
* add extra FL guard for safety
* move star rating multiplier into a constant
* Reorganise some things
* Add HD and SO to difficulty adjustment mods
* Move non-legacy mod multipliers back to PP
* Some merge fixes
* Fix application of flashlight rating multiplier
* Fix Hidden bonuses being applied when Blinds mod is in use
* Move part of speed OD scaling into difficulty
* Move length bonus back to PP
* Remove blinds special case
* Revert star rating multiplier decrease
* More balancing
---------
Co-authored-by: StanR <hi@stanr.info>
* Move osu!catch movement state into `CatchDifficultyHitObject`
In order to port `Movement` to an evaluator, the state has to be either
moved elsewhere or calculated inside the evaluator. The latter requires
backtracking for every hit object, which in the worst case is continued
until the beginning of the map is reached. Limiting backtracking can
lead to difficulty value changes.
Thus, the first option was chosen for its simplicity.
* Move osu!catch movement difficulty calculation to an evaluator
Makes the code more in line with the other game modes.
* Add documentation for `CatchDifficultyHitObject` fields
---------
Co-authored-by: James Wilson <tsunyoku@gmail.com>
* Move difficulty calculation fields from `Slider` to `OsuDifficultyHitObject`
* Remove redundant check
* Use `LastObject` where possible
* Update tests
* Make `LazyTravelDistance` `double`
---------
Co-authored-by: James Wilson <tsunyoku@gmail.com>
* Use `normalized_hitobject_radius` during osu!catch buzz slider detection
Currently the algorithm considers some buzz sliders as standstills when
in reality they require movement. This happens because `HalfCatcherWidth`
isn't normalized while `exactDistanceMoved` is, leading to an inaccurate
comparison.
`normalized_hitobject_radius` is the normalized value of `HalfCatcherWidth`
and replacing one with the other fixes the problem.
* Rename `normalized_hitobject_radius` to `normalized_half_catcher_width`
The current name is confusing because hit objects have no radius in the
context of osu!catch difficulty calculation. The new name conveys the
actual purpose of the value.
* Only set `normalized_half_catcher_width` in `CatchDifficultyHitObject`
Prevents potential bugs if the value were to be changed in one of the
classes but not in both.
* Use `CatchDifficultyHitObject.NORMALIZED_HALF_CATCHER_WIDTH` directly
Requested during code review.
---------
Co-authored-by: James Wilson <tsunyoku@gmail.com>
# temporary workaround for https://youtrack.jetbrains.com/issue/RIDER-130051/Cannot-resolve-symbol-inspections-incorrectly-firing-for-xmldoc-protected-member-references
# temporary workaround for https://youtrack.jetbrains.com/issue/RIDER-130381/Rider-does-not-respect-propagated-NoWarn-CS1591?backToIssues=false
dotnet_diagnostic.CS1591.severity=none
#license header
file_header_template=Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.\nSee the LICENCE file in the repository root for full licence text.
about:Got something you think should change or be added? Search for or start a new discussion!
- name:osu!stable issues
url:https://github.com/ppy/osu-stable-issues
about:For osu!(stable) - ie. the current "live" game version, check out the dedicated repository. Note that this is for serious bug reports only, not tech support.
url:https://t.me/jvnkosu_chat
about:Your jvnkosu! is not working right? Please contact us using our Telegram chat
A free-to-win rhythm game. Rhythm is just a *click* away!
*osu!* is a registered trademark of ppy Pty Ltd.
jvnkosu! is not affiliated with, or endorsed by ppy Pty Ltd., but makes use of its open-source components and resources.
This is the future – and final – iteration of the [osu!](https://osu.ppy.sh) game client which marks the beginning of an open era! Currently known by and released under the release codename "*lazer*". As in sharper than cutting-edge.
## License
Client source code is licensed under the MIT license, see the [LICENCE](LICENCE) file in repository root for more info.
## Status
Game assets are included as a NuGet package and licensed under the CC BY-NC 4.0, which prohibits commercial use. See [ppy/osu-resources](https://github.com/ppy/osu-resources) for more info.
This project is under constant development, but we do our best to keep things in a stable state. Players are encouraged to install from a release alongside their stable *osu!* client. This project will continue to evolve until we eventually reach the point where most users prefer it over the previous "osu!stable" release.
Registered trademarks "osu!" and "ppy" are property of ppy Pty Ltd., and protected by trademark law.
A few resources are available as starting points to getting involved and understanding the project:
## Compiling from source
Building jvnkosu! from source is pretty much possible (and welcome here).
- Detailed release changelogs are available on the [official osu! site](https://osu.ppy.sh/home/changelog/lazer).
- You can learn more about our approach to [project management](https://github.com/ppy/osu/wiki/Project-management).
- Track our current efforts [towards improving the game](https://github.com/orgs/ppy/projects/7/views/6).
First, you must have a desktop platform with [.NET Core SDK 8](https://dotnet.microsoft.com/download) installed. Windows, Linux, macOS should work well. You can check if you have the SDK installed by running `dotnet --version` in your command prompt/terminal.
## Running osu!
If you are just looking to give the game a whirl, you can grab the latest release for your platform:
You can also generally download a version for your current device from the [osu! site](https://osu.ppy.sh/home/download).
If your platform is unsupported or not listed above, there is still a chance you can run the release or manually build it by following the instructions below.
**For iOS/iPadOS users**: The iOS testflight link fills up very fast (Apple has a hard limit of 10,000 users). We reset it occasionally. Please do not ask about this. Check back regularly for link resets or follow [peppy](https://twitter.com/ppy) on twitter for announcements. Our goal is to get the game on mobile app stores very soon so we don't have to live with this limitation.
## Developing a custom ruleset
osu! is designed to allow user-created gameplay variations, called "rulesets". Building one of these allows a developer to harness the power of the osu! beatmap library, game engine, and general UX for a new style of gameplay. To get started working on a ruleset, we have some templates available [here](https://github.com/ppy/osu/tree/master/Templates).
You can see some examples of custom rulesets by visiting the [custom ruleset directory](https://github.com/ppy/osu/discussions/13096).
## Developing osu!
### Prerequisites
Please make sure you have the following prerequisites:
- A desktop platform with the [.NET 8.0 SDK](https://dotnet.microsoft.com/download) installed.
When working with the codebase, we recommend using an IDE with intelligent code completion and syntax highlighting, such as the latest version of [Visual Studio](https://visualstudio.microsoft.com/vs/), [JetBrains Rider](https://www.jetbrains.com/rider/), or [Visual Studio Code](https://code.visualstudio.com/) with the [EditorConfig](https://marketplace.visualstudio.com/items?itemName=EditorConfig.EditorConfig) and [C# Dev Kit](https://marketplace.visualstudio.com/items?itemName=ms-dotnettools.csdevkit) plugin installed.
### Downloading the source code
Clone the repository:
```shell
git clone https://github.com/ppy/osu
cd osu
Then, download the source code. You may download it as an archive and unzip it, but using [Git](https://git-scm.com/) instead is recommended:
To update the source code to the latest commit, run the following command inside the `osu` directory:
```shell
git pull
To **run** the project, switch to project's directory and run the following:
```
### Building
#### From an IDE
You should load the solution via one of the platform-specific `.slnf` files, rather than the main `.sln`. This will reduce dependencies and hide platforms that you don't care about. Valid `.slnf` files are:
-`osu.Desktop.slnf` (most common)
-`osu.Android.slnf`
-`osu.iOS.slnf`
Run configurations for the recommended IDEs (listed above) are included. You should use the provided Build/Run functionality of your IDE to get things going. When testing or building new components, it's highly encouraged you use the `osu! (Tests)` project/configuration. More information on this is provided [below](#contributing).
To build for mobile platforms, you will likely need to run `sudo dotnet workload restore` if you haven't done so previously. This will install Android/iOS tooling required to complete the build.
#### From CLI
You can also build and run *osu!* from the command-line with a single command:
```shell
dotnet run --project osu.Desktop
```
When running locally to do any kind of performance testing, make sure to add `-c Release` to the build command, as the overhead of running with the default `Debug` configuration can be large (especially when testing with local framework modifications as below).
If the build fails, try to restore NuGet packages with `dotnet restore`.
### Testing with resource/framework modifications
Sometimes it may be necessary to cross-test changes in [osu-resources](https://github.com/ppy/osu-resources) or [osu-framework](https://github.com/ppy/osu-framework). This can be quickly achieved using included commands:
Windows:
```ps
UseLocalFramework.ps1
UseLocalResources.ps1
To **compile**:
```
dotnet build osu.Desktop
```
macOS / Linux:
To reduce performance overhead in custom builds, it's recommended to build with the `-c Release` flag, that will use the release profile and remove possibly unneeded debugging code.
```ps
UseLocalFramework.sh
UseLocalResources.sh
```
Note that these commands assume you have the relevant project(s) checked out in adjacent directories:
```
|- osu // this repository
|- osu-framework
|- osu-resources
```
### Code analysis
Before committing your code, please run a code formatter. This can be achieved by running `dotnet format` in the command line, or using the `Format code` command in your IDE.
We have adopted some cross-platform, compiler integrated analyzers. They can provide warnings when you are editing, building inside IDE or from command line, as-if they are provided by the compiler itself.
JetBrains ReSharper InspectCode is also used for wider rule sets. You can run it from PowerShell with `.\InspectCode.ps1`. Alternatively, you can install ReSharper or use Rider to get inline support in your IDE of choice.
## Contributing
When it comes to contributing to the project, the two main things you can do to help out are reporting issues and submitting pull requests. Please refer to the [contributing guidelines](CONTRIBUTING.md) to understand how to help in the most effective way possible.
If you wish to help with localisation efforts, head over to [crowdin](https://crowdin.com/project/osu-web).
We love to reward quality contributions. If you have made a large contribution, or are a regular contributor, you are welcome to [submit an expense via opencollective](https://opencollective.com/ppy/expenses/new). If you have any questions, feel free to [reach out to peppy](mailto:pe@ppy.sh) before doing so.
## Licence
*osu!*'s code and framework are licensed under the [MIT licence](https://opensource.org/licenses/MIT). Please see [the licence file](LICENCE) for more information. [tl;dr](https://tldrlegal.com/license/mit-license) you can do whatever you want as long as you include the original copyright and license notice in any copy of the software/source.
Please note that this *does not cover* the usage of the "osu!" or "ppy" branding in any software, resources, advertising or promotion, as this is protected by trademark law.
Please also note that game resources are covered by a separate licence. Please see the [ppy/osu-resources](https://github.com/ppy/osu-resources) repository for clarifications.
### See the [original readme](README.original.md) for more info.
A free-to-win rhythm game. Rhythm is just a *click* away!
This is the future – and final – iteration of the [osu!](https://osu.ppy.sh) game client which marks the beginning of an open era! Currently known by and released under the release codename "*lazer*". As in sharper than cutting-edge.
## Status
This project is under constant development, but we do our best to keep things in a stable state. Players are encouraged to install from a release alongside their stable *osu!* client. This project will continue to evolve until we eventually reach the point where most users prefer it over the previous "osu!stable" release.
A few resources are available as starting points to getting involved and understanding the project:
- Detailed release changelogs are available on the [official osu! site](https://osu.ppy.sh/home/changelog/lazer).
- You can learn more about our approach to [project management](https://github.com/ppy/osu/wiki/Project-management).
- Track our current efforts [towards improving the game](https://github.com/orgs/ppy/projects/7/views/6).
## Running osu!
If you are just looking to give the game a whirl, you can grab the latest release for your platform:
You can also generally download a version for your current device from the [osu! site](https://osu.ppy.sh/home/download).
If your platform is unsupported or not listed above, there is still a chance you can run the release or manually build it by following the instructions below.
**For iOS/iPadOS users**: The iOS testflight link fills up very fast (Apple has a hard limit of 10,000 users). We reset it occasionally. Please do not ask about this. Check back regularly for link resets or follow [peppy](https://twitter.com/ppy) on twitter for announcements. Our goal is to get the game on mobile app stores very soon so we don't have to live with this limitation.
## Developing a custom ruleset
osu! is designed to allow user-created gameplay variations, called "rulesets". Building one of these allows a developer to harness the power of the osu! beatmap library, game engine, and general UX for a new style of gameplay. To get started working on a ruleset, we have some templates available [here](https://github.com/ppy/osu/tree/master/Templates).
You can see some examples of custom rulesets by visiting the [custom ruleset directory](https://github.com/ppy/osu/discussions/13096).
## Developing osu!
### Prerequisites
Please make sure you have the following prerequisites:
- A desktop platform with the [.NET 8.0 SDK](https://dotnet.microsoft.com/download) installed.
When working with the codebase, we recommend using an IDE with intelligent code completion and syntax highlighting, such as the latest version of [Visual Studio](https://visualstudio.microsoft.com/vs/), [JetBrains Rider](https://www.jetbrains.com/rider/), or [Visual Studio Code](https://code.visualstudio.com/) with the [EditorConfig](https://marketplace.visualstudio.com/items?itemName=EditorConfig.EditorConfig) and [C# Dev Kit](https://marketplace.visualstudio.com/items?itemName=ms-dotnettools.csdevkit) plugin installed.
### Downloading the source code
Clone the repository:
```shell
git clone https://github.com/ppy/osu
cd osu
```
To update the source code to the latest commit, run the following command inside the `osu` directory:
```shell
git pull
```
### Building
#### From an IDE
You should load the solution via one of the platform-specific `.slnf` files, rather than the main `.sln`. This will reduce dependencies and hide platforms that you don't care about. Valid `.slnf` files are:
-`osu.Desktop.slnf` (most common)
-`osu.Android.slnf`
-`osu.iOS.slnf`
Run configurations for the recommended IDEs (listed above) are included. You should use the provided Build/Run functionality of your IDE to get things going. When testing or building new components, it's highly encouraged you use the `osu! (Tests)` project/configuration. More information on this is provided [below](#contributing).
To build for mobile platforms, you will likely need to run `sudo dotnet workload restore` if you haven't done so previously. This will install Android/iOS tooling required to complete the build.
#### From CLI
You can also build and run *osu!* from the command-line with a single command:
```shell
dotnet run --project osu.Desktop
```
When running locally to do any kind of performance testing, make sure to add `-c Release` to the build command, as the overhead of running with the default `Debug` configuration can be large (especially when testing with local framework modifications as below).
If the build fails, try to restore NuGet packages with `dotnet restore`.
### Testing with resource/framework modifications
Sometimes it may be necessary to cross-test changes in [osu-resources](https://github.com/ppy/osu-resources) or [osu-framework](https://github.com/ppy/osu-framework). This can be quickly achieved using included commands:
Windows:
```ps
UseLocalFramework.ps1
UseLocalResources.ps1
```
macOS / Linux:
```ps
UseLocalFramework.sh
UseLocalResources.sh
```
Note that these commands assume you have the relevant project(s) checked out in adjacent directories:
```
|- osu // this repository
|- osu-framework
|- osu-resources
```
### Code analysis
Before committing your code, please run a code formatter. This can be achieved by running `dotnet format` in the command line, or using the `Format code` command in your IDE.
We have adopted some cross-platform, compiler integrated analyzers. They can provide warnings when you are editing, building inside IDE or from command line, as-if they are provided by the compiler itself.
JetBrains ReSharper InspectCode is also used for wider rule sets. You can run it from PowerShell with `.\InspectCode.ps1`. Alternatively, you can install ReSharper or use Rider to get inline support in your IDE of choice.
## Contributing
When it comes to contributing to the project, the two main things you can do to help out are reporting issues and submitting pull requests. Please refer to the [contributing guidelines](CONTRIBUTING.md) to understand how to help in the most effective way possible.
If you wish to help with localisation efforts, head over to [crowdin](https://crowdin.com/project/osu-web).
We love to reward quality contributions. If you have made a large contribution, or are a regular contributor, you are welcome to [submit an expense via opencollective](https://opencollective.com/ppy/expenses/new). If you have any questions, feel free to [reach out to peppy](mailto:pe@ppy.sh) before doing so.
## Licence
*osu!*'s code and framework are licensed under the [MIT licence](https://opensource.org/licenses/MIT). Please see [the licence file](LICENCE) for more information. [tl;dr](https://tldrlegal.com/license/mit-license) you can do whatever you want as long as you include the original copyright and license notice in any copy of the software/source.
Please note that this *does not cover* the usage of the "osu!" or "ppy" branding in any software, resources, advertising or promotion, as this is protected by trademark law.
Please also note that game resources are covered by a separate licence. Please see the [ppy/osu-resources](https://github.com/ppy/osu-resources) repository for clarifications.
// While .NET 8 only supports Windows 10 and above, running on Windows 7/8.1 may still work. We are limited by realm currently, as they choose to only support 8.1 and higher.
// See https://www.mongodb.com/docs/realm/sdk/dotnet/compatibility/
*Math.Pow((Math.Min(catchCurrent.StrainTime*catcherSpeedMultiplier,265)/265),1.5);// Edge Dashes are easier at lower ms values
}
// There is an edge case where horizontal back and forth sliders create "buzz" patterns which are repeated "movements" with a distance lower than
// the platter's width but high enough to be considered a movement due to the absolute_player_positioning_error and NORMALIZED_HALF_CATCHER_WIDTH offsets
// We are detecting this exact scenario. The first back and forth is counted but all subsequent ones are nullified.
// To achieve that, we need to store the exact distances (distance ignoring absolute_player_positioning_error and NORMALIZED_HALF_CATCHER_WIDTH)
/// Normalized position of <see cref="BaseObject"/>.
/// </summary>
publicreadonlyfloatNormalizedPosition;
/// <summary>
/// Normalized position of <see cref="LastObject"/>.
/// </summary>
publicreadonlyfloatLastNormalizedPosition;
/// <summary>
/// Normalized position of the player required to catch <see cref="BaseObject"/>, assuming the player moves as little as possible.
/// </summary>
publicfloatPlayerPosition{get;privateset;}
/// <summary>
/// Normalized position of the player after catching <see cref="LastObject"/>.
/// </summary>
publicfloatLastPlayerPosition{get;privateset;}
/// <summary>
/// Normalized distance between <see cref="LastPlayerPosition"/> and <see cref="PlayerPosition"/>.
/// </summary>
/// <remarks>
/// The sign of the value indicates the direction of the movement: negative is left and positive is right.
/// </remarks>
publicfloatDistanceMoved{get;privateset;}
/// <summary>
/// Normalized distance the player has to move from <see cref="LastPlayerPosition"/> in order to catch <see cref="BaseObject"/> at its <see cref="NormalizedPosition"/>.
/// </summary>
/// <remarks>
/// The sign of the value indicates the direction of the movement: negative is left and positive is right.
/// </remarks>
publicfloatExactDistanceMoved{get;privateset;}
/// <summary>
/// Milliseconds elapsed since the start time of the previous <see cref="CatchDifficultyHitObject"/>, with a minimum of 40ms.
*Math.Pow((Math.Min(catchCurrent.StrainTime*catcherSpeedMultiplier,265)/265),1.5);// Edge Dashes are easier at lower ms values
}
// There is an edge case where horizontal back and forth sliders create "buzz" patterns which are repeated "movements" with a distance lower than
// the platter's width but high enough to be considered a movement due to the absolute_player_positioning_error and normalized_hitobject_radius offsets
// We are detecting this exact scenario. The first back and forth is counted but all subsequent ones are nullified.
// To achieve that, we need to store the exact distances (distance ignoring absolute_player_positioning_error and normalized_hitobject_radius)
Some files were not shown because too many files have changed in this diff
Show More
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.