-
Notifications
You must be signed in to change notification settings - Fork 0
/
JudgementCalculator.java
111 lines (98 loc) · 2.94 KB
/
JudgementCalculator.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
/**
* This class determines the judgement for each key press.
*
* @author Team APCSA 2019
* @author Yijie Gui
* @since 2019-05-22 21:34
*/
@SuppressWarnings("WeakerAccess")
public class JudgementCalculator
{
/** Timings, see calculateTimings() method for more info. */
private final int[] timings;
/**
* Construct a Judgement controller.
*
* @param beatmap Beatmap
*/
public JudgementCalculator(Beatmap beatmap)
{
timings = calculateTimings(beatmap);
}
/**
* Calculate the value of each hit. A hit cannot miss, only ignored
* notes are considered missed.
*
* @param noteTime The in-game time of the note.
* @param gameTime The actual hit time of the note.
* @return Hit value (0 to 4). No notes = -1.
*/
public int calculateHitValue(int noteTime, int gameTime)
{
// How much ms is the player off by?
int off = Math.abs(noteTime - gameTime);
// Get the closest timing
for (int i = 0; i < timings.length; i++)
{
if (timings[i] > off)
{
return i;
}
}
// There are no notes.
return -1;
}
/**
* Calculate if a note is missed or not. A note is only missed when
* it went over the last judgement window.
*
* @param noteTime The in-game time of the note.
* @param gameTime Current in-game time.
* @return Missed or not.
*/
public boolean isMissed(int noteTime, int gameTime)
{
int late = gameTime - noteTime;
// Note is earlier than the game time.
if (late < 0) return false;
return timings[timings.length - 1] < late;
}
/**
* Calculate the timing values from a beatmap.
* Calculation Reference:
* https://www.reddit.com/r/osugame/comments/6phntt/difficulty_settings_table_with_all_values/
*
* @param beatmap The beatmap.
* @return Timings, sorted
*/
private static int[] calculateTimings(Beatmap beatmap)
{
// Get overall difficulty
double overall = Double.parseDouble(beatmap.getProperties().get("OverallDifficulty"));
double overallOffset = (overall * 3) + 0.5;
// Create timings array
int[] timings = new int[]
{
17, // Max
(int) (64 - overallOffset), // Great
(int) (97 - overallOffset), // Cool
(int) (127 - overallOffset), // Good
(int) (151 - overallOffset) // Bad
// If larger than Bad, ignore it.
// If player didn't hit, Poor.
};
// Add easy multiplier
for (int i = 0; i < timings.length; i++)
{
timings[i] *= (double) Constants.GAME_EASY_MULTIPLIER;
}
return timings;
}
// ###################
// Getters and Setters
// ###################
public int[] getTimings()
{
return timings;
}
}