Skip to content

Commit

Permalink
Add check for inconsistent timing points
Browse files Browse the repository at this point in the history
  • Loading branch information
Marvin Schürz committed Jan 6, 2025
1 parent 89c1843 commit 4857016
Show file tree
Hide file tree
Showing 2 changed files with 80 additions and 0 deletions.
2 changes: 2 additions & 0 deletions packages/common/src/rulesets/osu/verify/OsuBeatmapVerifier.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { CheckMarkerFormat } from '../../../verifier/checks/metadata/CheckMarker
import { CheckBgPresence } from '../../../verifier/checks/resources/CheckBgPresence';
import { CheckBgResolution } from '../../../verifier/checks/resources/CheckBgResolution';
import { CheckBeforeLine } from '../../../verifier/checks/timing/CheckBeforeLine';
import { CheckInconsistentTimingPoints } from '../../../verifier/checks/timing/CheckInconsistentTimingPoints';
import { CheckAbnormalNodes } from './compose/CheckAbnormalNodes';
import { CheckAbnormalSpacing } from './compose/CheckAbnormalSpacing';
import { CheckAmbiguity } from './compose/CheckAmbiguity';
Expand Down Expand Up @@ -69,6 +70,7 @@ export class OsuBeatmapVerifier extends BeatmapVerifier<OsuHitObject> {
new CheckBgPresence(),
new CheckBgResolution(),
new CheckCloseOverlap(),
new CheckInconsistentTimingPoints(),
];
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import type { CheckMetadata } from '../../BeatmapCheck';
import type { Issue } from '../../Issue';
import type { VerifierBeatmapSet } from '../../VerifierBeatmapSet';
import { almostEquals } from 'osucad-framework';
import { GeneralCheck } from '../../GeneralCheck';
import { IssueTemplate } from '../../template/IssueTemplate';

export class CheckInconsistentTimingPoints extends GeneralCheck {
override get metadata(): CheckMetadata {
return {
category: 'Timing',
message: 'Inconsistent timing points, meter signatures, or BPM.',
author: 'Naxess',
};
}

override templates = {

'Missing':
new IssueTemplate('problem', '{0:timestamp} Missing uninherited line, see {1:beatmap}.', 'timestamp - ', 'difficulty').withCause('A beatmap does not have an uninherited line which the reference beatmap does, or visa versa.'),

'Missing Minor':
new IssueTemplate('minor', '{0:timestamp} Has a decimally different offset to the one in {1:beatmap}.', 'timestamp - ', 'difficulty').withCause('Same as the first check, except includes issues caused by decimal unsnaps of uninherited lines.'),

'Inconsistent Meter':
new IssueTemplate('problem', '{0:timestamp} Inconsistent meter signature, see {1:beatmap}.', 'timestamp - ', 'difficulty').withCause('The meter signature of an uninherited timing line is different from the reference beatmap.'),

'Inconsistent BPM':
new IssueTemplate('problem', '{0:timestamp} Inconsistent BPM, see {1:beatmap}.', 'timestamp - ', 'difficulty').withCause('Same as the meter check, except checks BPM instead.'),

};

override async * getIssues(mapset: VerifierBeatmapSet): AsyncGenerator<Issue, void, undefined> {
const refBeatmap = mapset.beatmaps[0];
if (!refBeatmap)
return;

for (const beatmap of mapset.beatmaps) {
for (const timingPoint of refBeatmap.controlPoints.timingPoints) {
const other = beatmap.controlPoints.timingPoints.find(it => Math.round(it.time) === Math.round(timingPoint.time));

if (!other) {
yield this.createIssue(this.templates.Missing, beatmap, timingPoint.time, refBeatmap);

return;
}
else {
if (other.meter !== timingPoint.meter)
yield this.createIssue(this.templates['Inconsistent Meter'], beatmap, timingPoint.time, refBeatmap);
if (other.beatLength !== timingPoint.beatLength)
yield this.createIssue(this.templates['Inconsistent BPM'], beatmap, timingPoint.time, refBeatmap);

const respectiveLineExact = beatmap.controlPoints.timingPoints.find(other => almostEquals(other.time, timingPoint.time));

if (respectiveLineExact === null)
yield this.createIssue(this.templates['Missing Minor'], beatmap, timingPoint.time, refBeatmap);
}
}

// Check the other way around as well, to make sure the reference map has all uninherited lines this map has.
for (const timingPoint of beatmap.controlPoints.timingPoints) {
const other = refBeatmap.controlPoints.timingPoints.find(it => Math.round(it.time) === Math.round(timingPoint.time));

if (!other) {
yield this.createIssue(this.templates.Missing, beatmap, timingPoint.time, refBeatmap);

return;
}
else {
const respectiveLineExact = refBeatmap.controlPoints.timingPoints.find(other => almostEquals(other.time, timingPoint.time));

if (respectiveLineExact === null)
yield this.createIssue(this.templates['Missing Minor'], beatmap, timingPoint.time, refBeatmap);
}
}
}
}
}

0 comments on commit 4857016

Please sign in to comment.