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

feat: new judge #473

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
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
1 change: 1 addition & 0 deletions prpr/src/bin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -339,6 +339,7 @@ impl BinaryData for Note {
multiple_hint: false,
fake: r.read()?,
judge: JudgeStatus::NotJudged,
attr: false,
})
}

Expand Down
5 changes: 4 additions & 1 deletion prpr/src/core/chart.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,10 @@ impl Chart {
self.lines
.iter_mut()
.flat_map(|it| it.notes.iter_mut())
.for_each(|note| note.judge = JudgeStatus::NotJudged);
.for_each(|note| {
note.judge = JudgeStatus::NotJudged;
note.attr = false;
});
for line in &mut self.lines {
line.cache.reset(&mut line.notes);
}
Expand Down
1 change: 1 addition & 0 deletions prpr/src/core/note.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ pub struct Note {
pub multiple_hint: bool,
pub fake: bool,
pub judge: JudgeStatus,
pub attr: bool,
}

pub struct RenderConfig<'a> {
Expand Down
52 changes: 40 additions & 12 deletions prpr/src/judge.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

use crate::{
config::Config,
core::{BadNote, Chart, NoteKind, Point, Resource, Vector, NOTE_WIDTH_RATIO_BASE},
core::{BadNote, Chart, Note, NoteKind, Point, Resource, Vector, NOTE_WIDTH_RATIO_BASE},
ext::{get_viewport, NotNanExt},
};
use macroquad::prelude::{
Expand All @@ -19,7 +19,7 @@ use tracing::debug;
pub const FLICK_SPEED_THRESHOLD: f32 = 0.8;
pub const LIMIT_PERFECT: f32 = 0.08;
pub const LIMIT_GOOD: f32 = 0.16;
pub const LIMIT_BAD: f32 = 0.22;
pub const LIMIT_BAD: f32 = 0.18;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Mivik 这个是不是应该跟一下judge的版本

pub const UP_TOLERANCE: f32 = 0.05;
pub const DIST_FACTOR: f32 = 0.2;

Expand Down Expand Up @@ -512,7 +512,7 @@ impl Judge {
continue;
}
let t = time_of(touch);
let mut closest = (None, X_DIFF_MAX, LIMIT_BAD, LIMIT_BAD + (X_DIFF_MAX / NOTE_WIDTH_RATIO_BASE - 1.).max(0.) * DIST_FACTOR);
let mut closest = (None, X_DIFF_MAX, LIMIT_BAD, LIMIT_BAD + (X_DIFF_MAX / NOTE_WIDTH_RATIO_BASE - 1.).max(0.) * DIST_FACTOR, 0.);
for (line_id, ((line, pos), (idx, st))) in chart.lines.iter_mut().zip(pos.iter()).zip(self.notes.iter_mut()).enumerate() {
let Some(pos) = pos[id] else {
continue;
Expand All @@ -529,42 +529,70 @@ impl Judge {
if dt >= closest.3 {
break;
}
let dt = if dt < 0. { (dt + EARLY_OFFSET).min(0.).abs() } else { dt };
let x = &mut note.object.translation.0;
x.set_time(t);
let dist = (x.now() - pos.x).abs();
let posx = pos.x;
let dist = (x.now() - posx).abs();
if dist > X_DIFF_MAX {
continue;
}
if dt
> if matches!(note.kind, NoteKind::Click) {
LIMIT_BAD - LIMIT_PERFECT * (dist - 0.9).max(0.)
LIMIT_BAD
} else {
LIMIT_GOOD
}
{
continue;
}
let dt = if matches!(note.kind, NoteKind::Flick | NoteKind::Drag) {
dt + LIMIT_GOOD
dt.abs().max(LIMIT_GOOD)
} else {
dt
};
let key = dt + (dist / NOTE_WIDTH_RATIO_BASE - 1.).max(0.) * DIST_FACTOR;
if key < closest.3 {
closest = (Some((line_id, *id)), dist, dt, key);
closest = (Some((line_id, *id)), dist, dt, key, posx);
}
}
}
if let (Some((line_id, id)), _, dt, _) = closest {
if let (Some((line_id, id)), dist, dt, _, posx) = closest {
let drag_or_flick = |note: &mut Note| {
let x = &mut note.object.translation.0;
x.set_time(t);
let dist2 = (x.now() - posx).abs();
let dist = (dist2 - dist).abs();
let judge_time = t - note.time;
matches!(note.kind, NoteKind::Drag | NoteKind::Flick)
&& dist <= X_DIFF_MAX
&& !note.fake
&& !note.attr
&& judge_time >= -LIMIT_GOOD
&& judge_time <= LIMIT_BAD
};
let unattr_drag = chart.lines.iter_mut().any(|line| {
line.notes.iter_mut().any(|note| drag_or_flick(note))
});
let line = &mut chart.lines[line_id];
if matches!(line.notes[id as usize].kind, NoteKind::Drag) {
debug!("reject by drag");
// debug!("reject by drag");
continue;
}
if click {
if unattr_drag && dt > LIMIT_PERFECT { // flag drag
for line in &mut chart.lines {
for note in &mut line.notes {
if drag_or_flick(note) {
note.attr = true;
// debug!("flag drag");
}
}
}
continue;
}
// click & hold
let note = &mut line.notes[id as usize];
let dt = dt.abs();
if matches!(note.kind, NoteKind::Flick) {
continue; // to next loop
}
Expand Down Expand Up @@ -816,7 +844,7 @@ impl Judge {

fn auto_play_update(&mut self, res: &mut Resource, chart: &mut Chart) {
let t = res.time;
let spd = res.config.speed;
// let spd = res.config.speed;
let mut judgements = Vec::new();
for (line_id, (line, (idx, st))) in chart.lines.iter_mut().zip(self.notes.iter_mut()).enumerate() {
for id in &idx[*st..] {
Expand All @@ -839,7 +867,7 @@ impl Judge {
note.judge = if matches!(note.kind, NoteKind::Hold { .. }) {
note.hitsound.play(res);
self.judgements.borrow_mut().push((t, line_id as _, *id, Err(true)));
JudgeStatus::Hold(true, t, (t - note.time) / spd, false, f32::INFINITY)
JudgeStatus::Hold(true, note.time, 0. , false, f32::INFINITY)
} else {
judgements.push((line_id, *id));
JudgeStatus::Judged
Expand Down
1 change: 1 addition & 0 deletions prpr/src/parse/pec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,7 @@ pub fn parse_pec(source: &str, extra: ChartExtra) -> Result<Chart> {
multiple_hint: false,
fake,
judge: JudgeStatus::NotJudged,
attr: false,
});
if it.next() == Some("#") {
last_note!().speed = it.take_f32()?;
Expand Down
1 change: 1 addition & 0 deletions prpr/src/parse/pgr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,7 @@ fn parse_notes(r: f32, mut pgr: Vec<PgrNote>, speed: &mut AnimFloat, height: &mu
multiple_hint: false,
fake: false,
judge: JudgeStatus::NotJudged,
attr: false,
})
})
.collect()
Expand Down
1 change: 1 addition & 0 deletions prpr/src/parse/rpe.rs
Original file line number Diff line number Diff line change
Expand Up @@ -401,6 +401,7 @@ async fn parse_notes(
multiple_hint: false,
fake: note.is_fake != 0,
judge: JudgeStatus::NotJudged,
attr: false,
})
}
Ok(notes)
Expand Down