diff --git a/prpr/src/config.rs b/prpr/src/config.rs index 1e381230..c5b6bc5a 100644 --- a/prpr/src/config.rs +++ b/prpr/src/config.rs @@ -14,6 +14,7 @@ bitflags! { const AUTOPLAY = 1; const FLIP_X = 2; const FADE_OUT = 4; + const STRICT = 8; } } @@ -113,4 +114,9 @@ impl Config { pub fn flip_x(&self) -> bool { self.has_mod(Mods::FLIP_X) } + + #[inline] + pub fn strict(&self) -> bool { + self.has_mod(Mods::STRICT) + } } diff --git a/prpr/src/judge.rs b/prpr/src/judge.rs index 25ca3ef2..dc4dda68 100644 --- a/prpr/src/judge.rs +++ b/prpr/src/judge.rs @@ -359,6 +359,14 @@ impl Judge { } pub fn update(&mut self, res: &mut Resource, chart: &mut Chart, bad_notes: &mut Vec) { + + let (LIMIT_BAD_R, LIMIT_GOOD_R, LIMIT_PERFECT_R) = + if res.config.strict() { + (LIMIT_BAD, LIMIT_GOOD,LIMIT_PERFECT) + } else { + (LIMIT_BAD*0.5, LIMIT_GOOD*0.5, 0.5* LIMIT_PERFECT) + }; + if res.config.autoplay() { self.auto_play_update(res, chart); return; @@ -512,7 +520,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_R, LIMIT_BAD_R + (X_DIFF_MAX / NOTE_WIDTH_RATIO_BASE - 1.).max(0.) * DIST_FACTOR); 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; @@ -538,15 +546,15 @@ impl Judge { } if dt > if matches!(note.kind, NoteKind::Click) { - LIMIT_BAD - LIMIT_PERFECT * (dist - 0.9).max(0.) + LIMIT_BAD_R - LIMIT_PERFECT_R * (dist - 0.9).max(0.) } else { - LIMIT_GOOD + LIMIT_GOOD_R } { continue; } let dt = if matches!(note.kind, NoteKind::Flick | NoteKind::Drag) { - dt + LIMIT_GOOD + dt + LIMIT_GOOD_R } else { dt }; @@ -568,16 +576,16 @@ impl Judge { if matches!(note.kind, NoteKind::Flick) { continue; // to next loop } - if dt <= LIMIT_GOOD || matches!(note.kind, NoteKind::Hold { .. }) { + if dt <= LIMIT_GOOD_R || matches!(note.kind, NoteKind::Hold { .. }) { match note.kind { NoteKind::Click => { note.judge = JudgeStatus::Judged; - judgements.push((if dt <= LIMIT_PERFECT { Judgement::Perfect } else { Judgement::Good }, line_id, id, Some(t))); + judgements.push((if dt <= LIMIT_PERFECT_R { Judgement::Perfect } else { Judgement::Good }, line_id, id, Some(t))); } NoteKind::Hold { .. } => { note.hitsound.play(res); - self.judgements.borrow_mut().push((t, line_id as _, id, Err(dt <= LIMIT_PERFECT))); - note.judge = JudgeStatus::Hold(dt <= LIMIT_PERFECT, t, t, false, f32::INFINITY); + self.judgements.borrow_mut().push((t, line_id as _, id, Err(dt <= LIMIT_PERFECT_R))); + note.judge = JudgeStatus::Hold(dt <= LIMIT_PERFECT_R, t, t, false, f32::INFINITY); } _ => unreachable!(), }; @@ -619,14 +627,14 @@ impl Judge { { let note = &mut chart.lines[line_id].notes[id as usize]; let dt = (t - note.time).abs() / spd; - if dt <= if matches!(note.kind, NoteKind::Click) { LIMIT_BAD } else { LIMIT_GOOD } { + if dt <= if matches!(note.kind, NoteKind::Click) { LIMIT_BAD_R } else { LIMIT_GOOD_R } { match note.kind { NoteKind::Click => { note.judge = JudgeStatus::Judged; judgements.push(( - if dt <= LIMIT_PERFECT { + if dt <= LIMIT_PERFECT_R { Judgement::Perfect - } else if dt <= LIMIT_GOOD { + } else if dt <= LIMIT_GOOD_R { Judgement::Good } else { Judgement::Bad @@ -638,8 +646,8 @@ impl Judge { } NoteKind::Hold { .. } => { note.hitsound.play(res); - self.judgements.borrow_mut().push((t, line_id as _, id, Err(dt <= LIMIT_PERFECT))); - note.judge = JudgeStatus::Hold(dt <= LIMIT_PERFECT, t, (t - note.time) / spd, false, f32::INFINITY); + self.judgements.borrow_mut().push((t, line_id as _, id, Err(dt <= LIMIT_PERFECT_R))); + note.judge = JudgeStatus::Hold(dt <= LIMIT_PERFECT_R, t, (t - note.time) / spd, false, f32::INFINITY); } _ => unreachable!(), }; @@ -654,7 +662,7 @@ impl Judge { let note = &mut line.notes[*id as usize]; if let NoteKind::Hold { end_time, .. } = ¬e.kind { if let JudgeStatus::Hold(.., ref mut pre_judge, ref mut up_time) = note.judge { - if (*end_time - t) / spd <= LIMIT_BAD { + if (*end_time - t) / spd <= LIMIT_BAD_R { *pre_judge = true; continue; } @@ -679,12 +687,12 @@ impl Judge { } // process miss let dt = (t - note.time) / spd; - if dt > LIMIT_BAD { + if dt > LIMIT_BAD_R { note.judge = JudgeStatus::Judged; judgements.push((Judgement::Miss, line_id, *id, None)); continue; } - if -dt > LIMIT_BAD { + if -dt > LIMIT_BAD_R { break; } if !matches!(note.kind, NoteKind::Drag) && (self.key_down_count == 0 || !matches!(note.kind, NoteKind::Flick)) { @@ -698,7 +706,7 @@ impl Judge { || pos.iter().any(|it| { it.map_or(false, |it| { let dx = (it.x - x).abs(); - dx <= X_DIFF_MAX && dt <= (LIMIT_BAD - LIMIT_PERFECT * (dx - 0.9).max(0.)) + dx <= X_DIFF_MAX && dt <= (LIMIT_BAD_R - LIMIT_PERFECT_R * (dx - 0.9).max(0.)) }) }) { @@ -721,7 +729,7 @@ impl Judge { } } // TODO adjust - let ghost_t = t + LIMIT_GOOD; + let ghost_t = t + LIMIT_GOOD_R; if matches!(note.kind, NoteKind::Click) { if ghost_t < note.time { break;