Compare commits
701 Commits
old-testin
...
7074dcea8d
| Author | SHA1 | Date | |
|---|---|---|---|
| 7074dcea8d | |||
| d78de26260 | |||
| 7d38e6c8eb | |||
|
|
c4402e9ce5 | ||
|
|
de9cf751d2 | ||
|
|
0988552567 | ||
|
|
0fd0bd3580 | ||
|
|
16bc1de9fd | ||
|
|
0d74983551 | ||
|
|
b46656e7d3 | ||
|
|
482d31d598 | ||
|
|
f9e863af01 | ||
|
|
04767f44bb | ||
|
|
8fe63ade31 | ||
|
|
c1555af620 | ||
|
|
e911217980 | ||
|
|
ba2ae3218e | ||
|
|
b76a7e1bb6 | ||
|
|
6b10ef8709 | ||
|
|
43897457fb | ||
|
|
bb289363a2 | ||
|
|
28a18f768c | ||
|
|
45945e3bb1 | ||
|
|
cab50e94c8 | ||
|
|
ae032622ac | ||
|
|
a0ecbd7c87 | ||
|
|
459d5e8a45 | ||
|
|
9b55e1dfdb | ||
|
|
4c873787c1 | ||
|
|
43af89f75c | ||
|
|
f74a21c1e1 | ||
|
|
a028f0ba4a | ||
|
|
1aa42a73b1 | ||
|
|
d9e182230d | ||
|
|
65b49137ee | ||
|
|
2f96e96576 | ||
|
|
e64e0f0ca9 | ||
|
|
d37f59430b | ||
|
|
d748470754 | ||
|
|
2539bd90fa | ||
|
|
317be21569 | ||
|
|
b1044b6b2d | ||
|
|
c28c64940a | ||
|
|
b4f40639a1 | ||
|
|
7e7421e1ea | ||
|
|
1a8d2855d4 | ||
|
|
54a1417dd8 | ||
|
|
ce542b03db | ||
|
|
f20d182775 | ||
|
|
a7e6286396 | ||
|
|
521a40d860 | ||
|
|
564b6ebd0c | ||
|
|
7dfbab212e | ||
|
|
b831bcbcd4 | ||
|
|
c372f9b8f5 | ||
|
|
b0759ff34d | ||
|
|
d60a12a351 | ||
|
|
d27d0f40c1 | ||
|
|
ee9f8d5e92 | ||
|
|
9c8dfaf386 | ||
|
|
033e13cb3b | ||
|
|
b88cba0829 | ||
|
|
9c489aacf8 | ||
|
|
105342e5bf | ||
|
|
c72b6412ea | ||
|
|
2e659a79ec | ||
|
|
5131b188d1 | ||
|
|
7e2771c3f0 | ||
|
|
5174d8b918 | ||
|
|
32d10406c9 | ||
|
|
0dfb362b2d | ||
|
|
047ea7c09d | ||
|
|
cb597c4120 | ||
|
|
99ab245cf0 | ||
|
|
ee8d99034c | ||
|
|
5b1d4ceb9d | ||
|
|
ccb0224a1b | ||
|
|
5602281bd9 | ||
|
|
fabce18552 | ||
|
|
cb12d35d8f | ||
|
|
efc9a27d2d | ||
|
|
e2cbfb970e | ||
|
|
f39615a374 | ||
|
|
4916c87f14 | ||
|
|
a09489d4c0 | ||
|
|
d139f5997c | ||
|
|
29a39cbfb7 | ||
|
|
c144cf188a | ||
|
|
1e8b9a7639 | ||
|
|
69c2747883 | ||
|
|
d3b48364c5 | ||
|
|
9ae99648fb | ||
|
|
f9f927fa45 | ||
|
|
1153d17153 | ||
|
|
e15cb08b44 | ||
|
|
25d630898b | ||
|
|
48544733c3 | ||
|
|
d33a6d5512 | ||
|
|
110f11fa5e | ||
|
|
fb8c228d32 | ||
|
|
93d1a61dc2 | ||
|
|
83587e2265 | ||
|
|
f15e086bb0 | ||
|
|
9fa78123a6 | ||
|
|
7445efaecd | ||
|
|
86ab507e2e | ||
|
|
cc9a5ede29 | ||
|
|
6e03d5b00e | ||
|
|
71583bc06f | ||
|
|
94cec71502 | ||
|
|
42bf25442b | ||
|
|
fc4e29793d | ||
|
|
8e26cf4e1b | ||
|
|
810edebe87 | ||
|
|
2f459dd94e | ||
|
|
87f323a2e5 | ||
|
|
94d9de955f | ||
|
|
860427e4ae | ||
|
|
5afd6c6835 | ||
|
|
50426eb3c8 | ||
|
|
56bc80ffb9 | ||
|
|
c59e5bf335 | ||
|
|
655d725f0c | ||
|
|
15c49a729e | ||
|
|
3678ea0d0f | ||
|
|
dbce8886f8 | ||
|
|
a1136c3cea | ||
|
|
b613c1dcd5 | ||
|
|
cae8d3f4d4 | ||
|
|
f39b310eb5 | ||
|
|
efd4d12c21 | ||
|
|
60d98f0afd | ||
|
|
01982030ec | ||
|
|
bb83f3dcf2 | ||
|
|
0a4497db3c | ||
|
|
bb04a18060 | ||
|
|
7263551aa8 | ||
|
|
239951eda9 | ||
|
|
5cdf07c7e1 | ||
|
|
2efe0c95e6 | ||
|
|
a616fa61c9 | ||
|
|
e77e08c049 | ||
|
|
5231cfa1c7 | ||
|
|
40b331654e | ||
|
|
5e01dda411 | ||
|
|
5d4bb1bd37 | ||
|
|
1230da33a5 | ||
|
|
57222ea0c7 | ||
|
|
892e34b1f8 | ||
|
|
b8b6327624 | ||
|
|
85b8480e46 | ||
|
|
9e9b5cfc50 | ||
|
|
c9a50b40d0 | ||
|
|
8c21a5ba06 | ||
|
|
2ab7492759 | ||
|
|
cf09ed3e0d | ||
|
|
a774f19aef | ||
|
|
14d8cf7275 | ||
|
|
7d476b4b7c | ||
|
|
de97660fa4 | ||
|
|
5468215de8 | ||
|
|
1885ab86f5 | ||
|
|
586b2987a7 | ||
|
|
9bf52034d7 | ||
|
|
a53ba5e4ef | ||
|
|
35b9c74cf8 | ||
|
|
64a29313a8 | ||
|
|
d5ef0d75fc | ||
|
|
3b3bb266fc | ||
|
|
487347dac6 | ||
|
|
d7648afe96 | ||
|
|
c86f76b972 | ||
|
|
8e5eed63e1 | ||
|
|
b705313d3f | ||
|
|
5dd34f165f | ||
|
|
10651512a5 | ||
|
|
4c2ffa0f79 | ||
|
|
6997f89698 | ||
|
|
0ed4a8dbe5 | ||
|
|
c47f9c5259 | ||
|
|
a401c7d5e9 | ||
|
|
6185a81bd5 | ||
|
|
6d54d20943 | ||
|
|
02fbcaba23 | ||
|
|
7b7777bb56 | ||
|
|
ca7b850c8c | ||
|
|
88e5ac4834 | ||
|
|
b9d5606fd4 | ||
|
|
c8c91cedfa | ||
|
|
0c90cf3cef | ||
|
|
1a0193001d | ||
|
|
6bdb0e1cbb | ||
|
|
0d3b7ab6be | ||
|
|
8202ad18d0 | ||
|
|
fa5a278cf3 | ||
|
|
70321e2f89 | ||
|
|
c1fc1edd9c | ||
|
|
40e55ecb6e | ||
|
|
4a5dbea2a2 | ||
|
|
cffeb92248 | ||
|
|
2c56419fe9 | ||
|
|
add67b95c7 | ||
|
|
6fad798227 | ||
|
|
60690cbccc | ||
|
|
6329e3ee1b | ||
|
|
fa22d1f202 | ||
|
|
12eeab581e | ||
|
|
b5e93b98c9 | ||
|
|
786ea35274 | ||
|
|
d6bf4fd90d | ||
|
|
c407e07514 | ||
|
|
ed0051d119 | ||
|
|
99ea19d55c | ||
|
|
dba17b1fa6 | ||
|
|
fdf28474bf | ||
|
|
42dc73d849 | ||
|
|
6983227240 | ||
|
|
585ce682ef | ||
|
|
3db3b603bc | ||
|
|
1c537a3278 | ||
|
|
c88f10ca1b | ||
|
|
7fef2ce1de | ||
|
|
9a5fd0addb | ||
|
|
9c0b1a4914 | ||
|
|
acdb4477f7 | ||
|
|
4ff29339ed | ||
|
|
f1f4a0001b | ||
|
|
df1dc46603 | ||
|
|
84ec4bb866 | ||
|
|
9f0f9ef229 | ||
|
|
290b141d8f | ||
|
|
7cc025d8f4 | ||
|
|
978fc91b09 | ||
|
|
259c5708f1 | ||
|
|
b7559f93f2 | ||
|
|
c2604e22c7 | ||
|
|
dddd75b7f9 | ||
|
|
d3c9548b52 | ||
|
|
225f4d8814 | ||
|
|
d80934c344 | ||
|
|
6f038bff48 | ||
|
|
98c6f6afcd | ||
|
|
ff28839a09 | ||
|
|
52d5c986ef | ||
|
|
dd9e70b29c | ||
|
|
04e378c09f | ||
|
|
d4cf46e3cd | ||
|
|
42302c45ec | ||
|
|
e2dd4d86b4 | ||
|
|
6693307064 | ||
|
|
f0e7817dda | ||
|
|
a1d325370c | ||
|
|
1e8ffdf128 | ||
|
|
ea0b281f48 | ||
|
|
fdd13cd7e1 | ||
|
|
6354286452 | ||
|
|
6f146a5ce9 | ||
|
|
5d651628bc | ||
|
|
10dc1314f6 | ||
|
|
ce2d54f118 | ||
|
|
042f716b2a | ||
|
|
0ea060c612 | ||
|
|
ea8788a509 | ||
|
|
46b2d5374e | ||
|
|
8860eec9f9 | ||
|
|
8c86ff36a2 | ||
|
|
fdf9092f41 | ||
|
|
76f05a4837 | ||
|
|
ae1402c9cd | ||
|
|
741620d89c | ||
|
|
4ee4aac708 | ||
|
|
dfa7ac2082 | ||
|
|
2a0bafde8c | ||
|
|
91ee5eebc9 | ||
|
|
6bf95068ae | ||
|
|
6d999a8d8e | ||
|
|
c1d9de7e83 | ||
|
|
763dbe1494 | ||
|
|
65f7037e84 | ||
|
|
e62a01cf77 | ||
|
|
a60f262679 | ||
|
|
c0b644c905 | ||
|
|
cf73f8f9e6 | ||
|
|
7608ed4d87 | ||
|
|
eee88a3955 | ||
|
|
676b7a36da | ||
|
|
b5a989d31e | ||
|
|
a6489cd758 | ||
|
|
952fd0d493 | ||
|
|
06b89919be | ||
|
|
e1bde264bc | ||
|
|
e05b6f44b9 | ||
|
|
a8ada50549 | ||
|
|
1add946db4 | ||
|
|
a2ca650a9f | ||
|
|
cd433fea50 | ||
|
|
a6756157d1 | ||
|
|
367d133d2f | ||
|
|
1313883394 | ||
|
|
e8154080b3 | ||
|
|
b4ba327c1c | ||
|
|
c646b4e5ec | ||
|
|
15cb3b7a27 | ||
|
|
0551c75c6b | ||
|
|
2bf0dcf398 | ||
|
|
3302e2e180 | ||
|
|
79f1d77fed | ||
|
|
91718447db | ||
|
|
3f92b451d9 | ||
|
|
ed091dc9cd | ||
|
|
029d544720 | ||
|
|
876dcd060c | ||
|
|
b9a37453f9 | ||
|
|
c5a30d3244 | ||
|
|
96c414be86 | ||
|
|
30a60d83e2 | ||
|
|
ed760e6389 | ||
|
|
5d9ea9d699 | ||
|
|
874e3adcb7 | ||
|
|
e548cd40dc | ||
|
|
7ea1bbf91e | ||
|
|
27abce74ce | ||
|
|
8a581f5a90 | ||
|
|
3f4d1b798e | ||
|
|
d1a231cacf | ||
|
|
9c8d6e63a7 | ||
|
|
5abc0f93fe | ||
|
|
d5aa5b61ad | ||
|
|
f9e70f06b3 | ||
|
|
363b7cf3cb | ||
|
|
eeb4680795 | ||
|
|
f892d5fbaa | ||
|
|
0ba4e9e2a4 | ||
|
|
8de5726aa0 | ||
|
|
d3ed93280a | ||
|
|
37257a7a02 | ||
|
|
df1304af9e | ||
|
|
18fd4758d7 | ||
|
|
9acc632788 | ||
|
|
eb1417696a | ||
|
|
5de23e41cf | ||
|
|
5899800293 | ||
|
|
b15b4e70a5 | ||
|
|
40d8fb6316 | ||
|
|
a8989eb117 | ||
|
|
a81a77c60f | ||
|
|
4726489dba | ||
|
|
38c89a914b | ||
|
|
57f16646a3 | ||
|
|
9bad2c634b | ||
|
|
ae284fcf05 | ||
|
|
8a21c6814c | ||
|
|
f320592229 | ||
|
|
ee5cf25628 | ||
|
|
3e7f0f4c61 | ||
|
|
dda1c7f75b | ||
|
|
7652c91a53 | ||
|
|
1c1a3fbe8d | ||
|
|
7c1b1f4548 | ||
|
|
22082097f8 | ||
|
|
d35658985a | ||
|
|
576be6793b | ||
|
|
5e4e28ef00 | ||
|
|
a2d2c3287b | ||
|
|
23c68cbfea | ||
|
|
3f577aae60 | ||
|
|
2963ebae96 | ||
|
|
3157e82f51 | ||
|
|
b40ffd633f | ||
|
|
48de70e719 | ||
|
|
4f44d13e67 | ||
|
|
9b26b83d55 | ||
|
|
7f99650a04 | ||
|
|
0e8a294400 | ||
|
|
3ae98fd664 | ||
|
|
8c8ba2f3bc | ||
|
|
163ca25907 | ||
|
|
85747f8866 | ||
|
|
d05acc3d4f | ||
|
|
8cbcb0e74f | ||
|
|
d39020038b | ||
|
|
86a3c19547 | ||
|
|
53a5157a2f | ||
|
|
679c6d0229 | ||
|
|
86220622fb | ||
|
|
38360fde7b | ||
|
|
61d0b5a03c | ||
|
|
08364a7b97 | ||
|
|
465ec88371 | ||
|
|
4f2dfccb0f | ||
|
|
43e5aec16e | ||
|
|
59b3afe5aa | ||
|
|
fad53d9134 | ||
|
|
61c4a3dba0 | ||
|
|
8b49572c44 | ||
|
|
78a5654e1f | ||
|
|
2b90cbf59f | ||
|
|
ea289460b0 | ||
|
|
ff3397b6b7 | ||
|
|
a4fe0c924d | ||
|
|
33e49442c6 | ||
|
|
d0ac5cdeae | ||
|
|
23c595a136 | ||
|
|
9916e5bb1c | ||
|
|
25dab7258c | ||
|
|
b7b3e028ab | ||
|
|
88f80799c3 | ||
|
|
5839209d6f | ||
|
|
ff820f730e | ||
|
|
593cc37ea6 | ||
|
|
ebf9c19ad3 | ||
|
|
af08416880 | ||
|
|
3bd2050954 | ||
|
|
351a717795 | ||
|
|
00560cbfba | ||
|
|
b6dc64668e | ||
|
|
e0c4592dc7 | ||
|
|
1fcae16be9 | ||
|
|
212973bd63 | ||
|
|
5cba990940 | ||
|
|
974d3fa5e1 | ||
|
|
2fc621b4f3 | ||
|
|
ff4c281bd9 | ||
|
|
833617e279 | ||
|
|
e539660b14 | ||
|
|
d204b79342 | ||
|
|
54f9360814 | ||
|
|
19cfe9abe6 | ||
|
|
0a2fc12061 | ||
|
|
e1ce1e3188 | ||
|
|
464cc23393 | ||
|
|
338b987ea9 | ||
|
|
04bd381ee3 | ||
|
|
affe295f50 | ||
|
|
bd29c46bd7 | ||
|
|
28a6d6211c | ||
|
|
334a54e6f7 | ||
|
|
a6545bea68 | ||
|
|
7e823af70b | ||
|
|
9f40d630dc | ||
|
|
1cf14952de | ||
|
|
2d119f11ec | ||
|
|
dad138223b | ||
|
|
a23024d80e | ||
|
|
9f57be7410 | ||
|
|
853836a48b | ||
|
|
24a0de1020 | ||
|
|
ebb898f67c | ||
|
|
e2ed5208fe | ||
|
|
e07b828f30 | ||
|
|
e2a245b049 | ||
|
|
57cbe20c12 | ||
|
|
646e6de5df | ||
|
|
191ec072a8 | ||
|
|
1cff386b3a | ||
|
|
71be574c2b | ||
|
|
6e41332ea3 | ||
|
|
3c084c60aa | ||
|
|
3b9b030aad | ||
|
|
d421678d34 | ||
|
|
056d832371 | ||
|
|
4e83814d5a | ||
|
|
8ff2329e22 | ||
|
|
6bf25d700c | ||
|
|
5163b8f5f3 | ||
|
|
2e324fe856 | ||
|
|
8347f83f9c | ||
|
|
e34d266987 | ||
|
|
a6e1713514 | ||
|
|
10ebb5286f | ||
|
|
69fee16eee | ||
|
|
f3fa1122c2 | ||
|
|
0f018988b5 | ||
|
|
4a60d7fe71 | ||
|
|
69250b3260 | ||
|
|
60d9c358b8 | ||
|
|
ef3338ba93 | ||
|
|
99b00ab72f | ||
|
|
56ef5eae14 | ||
|
|
2cb2167765 | ||
|
|
206578bf10 | ||
|
|
36de88f399 | ||
|
|
0bcb3c5839 | ||
|
|
2acc2a84db | ||
|
|
64d16776be | ||
|
|
2d06c2b1a6 | ||
|
|
81f03957d8 | ||
|
|
ecaf3e05d4 | ||
|
|
2d85fe8133 | ||
|
|
0af07b97c5 | ||
|
|
03f44705b3 | ||
|
|
033a73e969 | ||
|
|
1340e18d93 | ||
|
|
43e217120d | ||
|
|
dc53198577 | ||
|
|
95cf050298 | ||
|
|
0bfff2bf88 | ||
|
|
fa32be37d6 | ||
|
|
e4d7bc3896 | ||
|
|
520baf6c50 | ||
|
|
a1d4d44151 | ||
|
|
a3a5b2ca92 | ||
|
|
cb32d2da3e | ||
|
|
4ee7e6f787 | ||
|
|
c2c1fa4d4c | ||
|
|
339aad42a7 | ||
|
|
a2872ee870 | ||
|
|
c6a8d9a150 | ||
|
|
6eec2b0ff8 | ||
|
|
0999e3f048 | ||
|
|
71386fe465 | ||
|
|
f58e4e4862 | ||
|
|
0bebabba94 | ||
|
|
95233fc638 | ||
|
|
277e00c74e | ||
|
|
a25f1cde25 | ||
|
|
2ed37ecbbc | ||
|
|
554961036e | ||
|
|
dbcc7cc09d | ||
|
|
d9dad4c3a8 | ||
|
|
0787345a84 | ||
|
|
9d07ad2761 | ||
|
|
1ab922af12 | ||
|
|
44df9047ae | ||
|
|
17143ca0a8 | ||
|
|
3712093158 | ||
|
|
df524d68fd | ||
|
|
daaea093f0 | ||
|
|
469aa7b303 | ||
|
|
e094eefafb | ||
|
|
4cce6aa123 | ||
|
|
bba4329ab5 | ||
|
|
25ba3f2dc6 | ||
|
|
ecc51d4701 | ||
|
|
32454caaa9 | ||
|
|
0f53886784 | ||
|
|
f598d8b108 | ||
|
|
f273163e58 | ||
|
|
6de1f0cd4d | ||
|
|
c475b4bc4b | ||
|
|
276757315f | ||
|
|
a82d0c3b51 | ||
|
|
4fee1547e3 | ||
|
|
a4215e0442 | ||
|
|
577cf7d1e7 | ||
|
|
09178b5dc4 | ||
|
|
16c4967ee4 | ||
|
|
e526de7f40 | ||
|
|
93a64dad89 | ||
|
|
897cb2c1a9 | ||
|
|
de0c191c47 | ||
|
|
61874e59e0 | ||
|
|
13aeed15f9 | ||
|
|
094860bfea | ||
|
|
44f535dcef | ||
|
|
f5bd888078 | ||
|
|
90d7615432 | ||
|
|
7a32e0eebf | ||
|
|
78043fa782 | ||
|
|
729cd722bd | ||
|
|
8da1fde981 | ||
|
|
1de97712f1 | ||
|
|
83ddcf7b02 | ||
|
|
2e7edf8c1f | ||
|
|
61ecd18d24 | ||
|
|
9e67cf503b | ||
|
|
62fd61def4 | ||
|
|
c120f0ebab | ||
|
|
5bf6a75b50 | ||
|
|
b71a26fcec | ||
|
|
5f9639fc3f | ||
|
|
61bf68f336 | ||
|
|
f581f85eb2 | ||
|
|
b07cd2daa4 | ||
|
|
3b635f6919 | ||
|
|
07817dce70 | ||
|
|
67e0348fa8 | ||
|
|
190b5535d7 | ||
|
|
83f9eba1d1 | ||
| 86f0159e65 | |||
| ae5a64ba81 | |||
| e3a7ae30cd | |||
| b6f845d99c | |||
| a1d6bda63e | |||
| 547d22a4b5 | |||
| b4c530ac04 | |||
| 5af05d2479 | |||
| 43ab18ffea | |||
| 9f59259a40 | |||
| 82b3015fcc | |||
| 68f92ab57c | |||
| d76d4d9a35 | |||
|
|
bb7417c099 | ||
|
|
066e093987 | ||
|
|
56e0c3e65d | ||
|
|
89d7726903 | ||
|
|
36f1bfef07 | ||
|
|
118f07878a | ||
|
|
e144968893 | ||
|
|
d2ffea41c6 | ||
|
|
a8be9b1381 | ||
| 490a6fd724 | |||
|
|
4b0017dfea | ||
| 237e1828f8 | |||
| 3413f722f7 | |||
| 9f779dac03 | |||
| 0727c53cdc | |||
| a57ff24191 | |||
| bdb3418b67 | |||
| 936640edeb | |||
| 1187d03333 | |||
| 3bd996ee43 | |||
| 37b9f91d42 | |||
| 1a5a5606dc | |||
| 87ff1051e9 | |||
| 2e4b0ff197 | |||
| 499f410c94 | |||
| 616c0d8ecd | |||
| ed889138a0 | |||
|
|
bb017ade64 | ||
|
|
549cc08bfe | ||
|
|
96dd95940f | ||
|
|
a30f08be80 | ||
| 18075bef29 | |||
| bc7780a870 | |||
| 8930b8fadb | |||
| 2d457f4305 | |||
| a784734f94 | |||
| ecfd4764e7 | |||
| f5ca5083d6 | |||
| 1d7c77d8d6 | |||
| 774e52fbd6 | |||
| a9d7a9d5d5 | |||
| f7069b1009 | |||
| c3ce5dc787 | |||
| 98076e2092 | |||
| b7d1092f90 | |||
| 08db90c278 | |||
| b7e36164c3 | |||
| 0f5f13858d | |||
| 89a0c75156 | |||
| ab7e5c94f1 | |||
| 8dc9ea4553 | |||
| dcf553c252 | |||
| 43f3a506ea | |||
| ab51579c27 | |||
| d8e977c05f | |||
| c023767df9 | |||
|
|
8755a01622 | ||
|
|
901044d690 | ||
|
|
90d1725603 | ||
|
|
78eaad13ae | ||
|
|
511921c1f7 | ||
|
|
e2681c4163 | ||
|
|
1f2f86b016 | ||
|
|
fa7bd482d2 | ||
|
|
c8762762f9 | ||
|
|
9333ef361b | ||
|
|
1cf9c04756 | ||
|
|
67849ca418 | ||
|
|
0777bdbfc5 | ||
|
|
798f6bdcc7 | ||
|
|
f38162c550 | ||
|
|
b663fe17ab | ||
|
|
3c1d45b896 | ||
|
|
259bc53699 | ||
|
|
87834d1693 | ||
|
|
f1539167eb | ||
|
|
ff6f797a3e | ||
|
|
bfa45a23ce | ||
|
|
c80fe7ab82 | ||
|
|
d85c2ee623 | ||
|
|
b4b26e3a1d | ||
| d47e26f1ae | |||
| b0e5ae1109 | |||
| 47b859ab17 | |||
| 5e523eb0b1 | |||
|
|
d912f8c3b9 | ||
| 65f275106e | |||
| 6e374762fd | |||
| 80646a166c | |||
| 8f0510d903 | |||
| 02e7000ee4 | |||
| 081355864e | |||
| 6435a835d1 | |||
| 628181a883 | |||
| 835329efd3 | |||
| 5399943118 | |||
| d07f82f6f4 | |||
| 5b186bb740 | |||
| 6cb99c13c2 | |||
| 96008e06ab | |||
| 590b0a8028 | |||
| 70f7f09a83 | |||
| 490137405f | |||
| f3c6f53f70 | |||
| 8cb5c682b4 | |||
| c3d79295d3 | |||
| f31d310135 | |||
| 26029de27d | |||
| c37f72f567 |
12
.github/ISSUE_TEMPLATE/config.yml
vendored
12
.github/ISSUE_TEMPLATE/config.yml
vendored
@@ -1,12 +1,6 @@
|
|||||||
blank_issues_enabled: false
|
blank_issues_enabled: true
|
||||||
contact_links:
|
contact_links:
|
||||||
- name: Help
|
- name: Help
|
||||||
url: https://github.com/ppy/osu/discussions/categories/q-a
|
url: https://t.me/jvnkosu_chat
|
||||||
about: osu! not working or performing as you'd expect? Not sure it's a bug? Check the Q&A section!
|
about: Your jvnkosu! is not working right? Please contact us using our Telegram chat
|
||||||
- name: Suggestions or feature request
|
|
||||||
url: https://github.com/ppy/osu/discussions/categories/ideas
|
|
||||||
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.
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
name: Update osu-web mod definitions
|
name: Update osu-web mod definitions (DO NOT USE YET!!!!!)
|
||||||
on:
|
on:
|
||||||
push:
|
workflow_dispatch:
|
||||||
tags:
|
# push:
|
||||||
- '*'
|
# tags:
|
||||||
|
# - '*'
|
||||||
|
|
||||||
|
|
||||||
permissions:
|
permissions:
|
||||||
contents: read # to fetch code (actions/checkout)
|
contents: read # to fetch code (actions/checkout)
|
||||||
10
.github/workflows/ci.yml
vendored
10
.github/workflows/ci.yml
vendored
@@ -1,4 +1,10 @@
|
|||||||
on: [push, pull_request]
|
on:
|
||||||
|
push:
|
||||||
|
tags:
|
||||||
|
- '*'
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
|
||||||
name: Continuous Integration
|
name: Continuous Integration
|
||||||
concurrency:
|
concurrency:
|
||||||
group: ${{ github.workflow }}-${{ github.ref }}
|
group: ${{ github.workflow }}-${{ github.ref }}
|
||||||
@@ -33,7 +39,7 @@ jobs:
|
|||||||
key: inspectcode-${{ hashFiles('.config/dotnet-tools.json', '.github/workflows/ci.yml', 'osu.sln*', 'osu*.slnf', '.editorconfig', '.globalconfig', 'CodeAnalysis/*', '**/*.csproj', '**/*.props') }}
|
key: inspectcode-${{ hashFiles('.config/dotnet-tools.json', '.github/workflows/ci.yml', 'osu.sln*', 'osu*.slnf', '.editorconfig', '.globalconfig', 'CodeAnalysis/*', '**/*.csproj', '**/*.props') }}
|
||||||
|
|
||||||
- name: Dotnet code style
|
- name: Dotnet code style
|
||||||
run: dotnet build -c Debug -warnaserror osu.Desktop.slnf -p:EnforceCodeStyleInBuild=true
|
run: dotnet build -c Debug -warnaserror osu.Desktop.slnf
|
||||||
|
|
||||||
- name: CodeFileSanity
|
- name: CodeFileSanity
|
||||||
run: |
|
run: |
|
||||||
|
|||||||
3
.github/workflows/deploy.yml
vendored
3
.github/workflows/deploy.yml
vendored
@@ -4,6 +4,7 @@ on:
|
|||||||
push:
|
push:
|
||||||
tags:
|
tags:
|
||||||
- '*'
|
- '*'
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
notify_pending_production_deploy:
|
notify_pending_production_deploy:
|
||||||
@@ -12,7 +13,7 @@ jobs:
|
|||||||
- name: Submit pending deployment notification
|
- name: Submit pending deployment notification
|
||||||
run: |
|
run: |
|
||||||
export TITLE="Pending osu Production Deployment: $GITHUB_REF_NAME"
|
export TITLE="Pending osu Production Deployment: $GITHUB_REF_NAME"
|
||||||
export URL="https://github.com/ppy/osu/actions/runs/$GITHUB_RUN_ID"
|
export URL="https://github.com/jvnkosu-dev/client/actions/runs/$GITHUB_RUN_ID"
|
||||||
export DESCRIPTION="Awaiting approval for building NuGet packages for tag $GITHUB_REF_NAME:
|
export DESCRIPTION="Awaiting approval for building NuGet packages for tag $GITHUB_REF_NAME:
|
||||||
[View Workflow Run]($URL)"
|
[View Workflow Run]($URL)"
|
||||||
export ACTOR_ICON="https://avatars.githubusercontent.com/u/$GITHUB_ACTOR_ID"
|
export ACTOR_ICON="https://avatars.githubusercontent.com/u/$GITHUB_ACTOR_ID"
|
||||||
|
|||||||
8
.github/workflows/sentry-release.yml
vendored
8
.github/workflows/sentry-release.yml
vendored
@@ -21,9 +21,9 @@ jobs:
|
|||||||
uses: getsentry/action-release@v1
|
uses: getsentry/action-release@v1
|
||||||
env:
|
env:
|
||||||
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
|
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
|
||||||
SENTRY_ORG: ppy
|
SENTRY_ORG: jvnkosu
|
||||||
SENTRY_PROJECT: osu
|
SENTRY_PROJECT: client
|
||||||
SENTRY_URL: https://sentry.ppy.sh/
|
SENTRY_URL: https://satellite.jvnko.boats/
|
||||||
with:
|
with:
|
||||||
environment: production
|
environment: production
|
||||||
version: osu@${{ github.ref_name }}
|
version: jvnkosu@${{ github.ref_name }}
|
||||||
|
|||||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -19,6 +19,7 @@ bld/
|
|||||||
[Bb]in/
|
[Bb]in/
|
||||||
[Oo]bj/
|
[Oo]bj/
|
||||||
[Ll]og/
|
[Ll]og/
|
||||||
|
[Pp]ub/
|
||||||
|
|
||||||
# Visual Studio 2015 cache/options directory
|
# Visual Studio 2015 cache/options directory
|
||||||
.vs/
|
.vs/
|
||||||
@@ -343,4 +344,4 @@ inspectcode
|
|||||||
FodyWeavers.xsd
|
FodyWeavers.xsd
|
||||||
|
|
||||||
.idea/.idea.osu.Desktop/.idea/misc.xml
|
.idea/.idea.osu.Desktop/.idea/misc.xml
|
||||||
.idea/.idea.osu.Android/.idea/deploymentTargetDropDown.xml
|
.idea/.idea.osu.Android/.idea/deploymentTargetDropDown.xml
|
||||||
36
.vscode/launch.json
vendored
36
.vscode/launch.json
vendored
@@ -7,9 +7,9 @@
|
|||||||
"request": "launch",
|
"request": "launch",
|
||||||
"program": "dotnet",
|
"program": "dotnet",
|
||||||
"args": [
|
"args": [
|
||||||
"${workspaceRoot}/osu.Desktop/bin/Debug/net8.0/osu!.dll"
|
"${workspaceFolder}/osu.Desktop/bin/Debug/net8.0/osu!.dll"
|
||||||
],
|
],
|
||||||
"cwd": "${workspaceRoot}",
|
"cwd": "${workspaceFolder}",
|
||||||
"preLaunchTask": "Build osu! (Debug)",
|
"preLaunchTask": "Build osu! (Debug)",
|
||||||
"console": "internalConsole"
|
"console": "internalConsole"
|
||||||
},
|
},
|
||||||
@@ -19,9 +19,9 @@
|
|||||||
"request": "launch",
|
"request": "launch",
|
||||||
"program": "dotnet",
|
"program": "dotnet",
|
||||||
"args": [
|
"args": [
|
||||||
"${workspaceRoot}/osu.Desktop/bin/Release/net8.0/osu!.dll"
|
"${workspaceFolder}/osu.Desktop/bin/Release/net8.0/osu!.dll"
|
||||||
],
|
],
|
||||||
"cwd": "${workspaceRoot}",
|
"cwd": "${workspaceFolder}",
|
||||||
"preLaunchTask": "Build osu! (Release)",
|
"preLaunchTask": "Build osu! (Release)",
|
||||||
"console": "internalConsole"
|
"console": "internalConsole"
|
||||||
},
|
},
|
||||||
@@ -31,9 +31,9 @@
|
|||||||
"request": "launch",
|
"request": "launch",
|
||||||
"program": "dotnet",
|
"program": "dotnet",
|
||||||
"args": [
|
"args": [
|
||||||
"${workspaceRoot}/osu.Game.Tests/bin/Debug/net8.0/osu.Game.Tests.dll"
|
"${workspaceFolder}/osu.Game.Tests/bin/Debug/net8.0/osu.Game.Tests.dll"
|
||||||
],
|
],
|
||||||
"cwd": "${workspaceRoot}",
|
"cwd": "${workspaceFolder}",
|
||||||
"preLaunchTask": "Build tests (Debug)",
|
"preLaunchTask": "Build tests (Debug)",
|
||||||
"console": "internalConsole"
|
"console": "internalConsole"
|
||||||
},
|
},
|
||||||
@@ -43,9 +43,9 @@
|
|||||||
"request": "launch",
|
"request": "launch",
|
||||||
"program": "dotnet",
|
"program": "dotnet",
|
||||||
"args": [
|
"args": [
|
||||||
"${workspaceRoot}/osu.Game.Tests/bin/Release/net8.0/osu.Game.Tests.dll"
|
"${workspaceFolder}/osu.Game.Tests/bin/Release/net8.0/osu.Game.Tests.dll"
|
||||||
],
|
],
|
||||||
"cwd": "${workspaceRoot}",
|
"cwd": "${workspaceFolder}",
|
||||||
"preLaunchTask": "Build tests (Release)",
|
"preLaunchTask": "Build tests (Release)",
|
||||||
"console": "internalConsole"
|
"console": "internalConsole"
|
||||||
},
|
},
|
||||||
@@ -55,10 +55,10 @@
|
|||||||
"request": "launch",
|
"request": "launch",
|
||||||
"program": "dotnet",
|
"program": "dotnet",
|
||||||
"args": [
|
"args": [
|
||||||
"${workspaceRoot}/osu.Desktop/bin/Debug/net8.0/osu!.dll",
|
"${workspaceFolder}/osu.Desktop/bin/Debug/net8.0/osu!.dll",
|
||||||
"--tournament"
|
"--tournament"
|
||||||
],
|
],
|
||||||
"cwd": "${workspaceRoot}",
|
"cwd": "${workspaceFolder}",
|
||||||
"preLaunchTask": "Build osu! (Debug)",
|
"preLaunchTask": "Build osu! (Debug)",
|
||||||
"console": "internalConsole"
|
"console": "internalConsole"
|
||||||
},
|
},
|
||||||
@@ -68,10 +68,10 @@
|
|||||||
"request": "launch",
|
"request": "launch",
|
||||||
"program": "dotnet",
|
"program": "dotnet",
|
||||||
"args": [
|
"args": [
|
||||||
"${workspaceRoot}/osu.Desktop/bin/Release/net8.0/osu!.dll",
|
"${workspaceFolder}/osu.Desktop/bin/Release/net8.0/osu!.dll",
|
||||||
"--tournament"
|
"--tournament"
|
||||||
],
|
],
|
||||||
"cwd": "${workspaceRoot}",
|
"cwd": "${workspaceFolder}",
|
||||||
"preLaunchTask": "Build osu! (Release)",
|
"preLaunchTask": "Build osu! (Release)",
|
||||||
"console": "internalConsole"
|
"console": "internalConsole"
|
||||||
},
|
},
|
||||||
@@ -81,10 +81,10 @@
|
|||||||
"request": "launch",
|
"request": "launch",
|
||||||
"program": "dotnet",
|
"program": "dotnet",
|
||||||
"args": [
|
"args": [
|
||||||
"${workspaceRoot}/osu.Game.Tournament.Tests/bin/Debug/net8.0/osu.Game.Tournament.Tests.dll",
|
"${workspaceFolder}/osu.Game.Tournament.Tests/bin/Debug/net8.0/osu.Game.Tournament.Tests.dll",
|
||||||
"--tournament"
|
"--tournament"
|
||||||
],
|
],
|
||||||
"cwd": "${workspaceRoot}",
|
"cwd": "${workspaceFolder}",
|
||||||
"preLaunchTask": "Build tournament tests (Debug)",
|
"preLaunchTask": "Build tournament tests (Debug)",
|
||||||
"console": "internalConsole"
|
"console": "internalConsole"
|
||||||
},
|
},
|
||||||
@@ -94,10 +94,10 @@
|
|||||||
"request": "launch",
|
"request": "launch",
|
||||||
"program": "dotnet",
|
"program": "dotnet",
|
||||||
"args": [
|
"args": [
|
||||||
"${workspaceRoot}/osu.Game.Tournament.Tests/bin/Debug/net8.0/osu.Game.Tournament.Tests.dll",
|
"${workspaceFolder}/osu.Game.Tournament.Tests/bin/Debug/net8.0/osu.Game.Tournament.Tests.dll",
|
||||||
"--tournament"
|
"--tournament"
|
||||||
],
|
],
|
||||||
"cwd": "${workspaceRoot}",
|
"cwd": "${workspaceFolder}",
|
||||||
"preLaunchTask": "Build tournament tests (Release)",
|
"preLaunchTask": "Build tournament tests (Release)",
|
||||||
"console": "internalConsole"
|
"console": "internalConsole"
|
||||||
},
|
},
|
||||||
@@ -105,12 +105,12 @@
|
|||||||
"name": "Benchmark",
|
"name": "Benchmark",
|
||||||
"type": "coreclr",
|
"type": "coreclr",
|
||||||
"request": "launch",
|
"request": "launch",
|
||||||
"program": "${workspaceRoot}/osu.Game.Benchmarks/bin/Release/net8.0/osu.Game.Benchmarks.dll",
|
"program": "${workspaceFolder}/osu.Game.Benchmarks/bin/Release/net8.0/osu.Game.Benchmarks.dll",
|
||||||
"args": [
|
"args": [
|
||||||
"--filter",
|
"--filter",
|
||||||
"*"
|
"*"
|
||||||
],
|
],
|
||||||
"cwd": "${workspaceRoot}",
|
"cwd": "${workspaceFolder}",
|
||||||
"preLaunchTask": "Build benchmarks",
|
"preLaunchTask": "Build benchmarks",
|
||||||
"console": "internalConsole"
|
"console": "internalConsole"
|
||||||
}
|
}
|
||||||
|
|||||||
3
.vscode/settings.json
vendored
Normal file
3
.vscode/settings.json
vendored
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"dotnet.defaultSolution": "osu.Desktop.slnf"
|
||||||
|
}
|
||||||
@@ -55,9 +55,7 @@ When in doubt, it's probably best to start with a discussion first. We will esca
|
|||||||
|
|
||||||
While pull requests from unaffiliated contributors are welcome, please note that due to significant community interest and limited review throughput, the core team's primary focus is on the issues which are currently [on the roadmap](https://github.com/orgs/ppy/projects/7/views/6). Reviewing PRs that fall outside of the scope of the roadmap is done on a best-effort basis, so please be aware that it may take a while before a core maintainer gets around to review your change.
|
While pull requests from unaffiliated contributors are welcome, please note that due to significant community interest and limited review throughput, the core team's primary focus is on the issues which are currently [on the roadmap](https://github.com/orgs/ppy/projects/7/views/6). Reviewing PRs that fall outside of the scope of the roadmap is done on a best-effort basis, so please be aware that it may take a while before a core maintainer gets around to review your change.
|
||||||
|
|
||||||
The [issue tracker](https://github.com/ppy/osu/issues) should provide plenty of issues to start with. We also have a [`good first issue`](https://github.com/ppy/osu/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22) label, although from experience it is not used very often, as it is relatively rare that we can spot an issue that will definitively be a good first issue for a new contributor regardless of their programming experience.
|
The [issue tracker](https://github.com/ppy/osu/issues) should provide plenty of issues to start with. In the case of simple issues, a direct PR is okay. However, if you decide to work on an existing issue which doesn't seem trivial, **please ask us first**. This way we can try to estimate if it is a good fit for you and provide the correct direction on how to address it. In addition, note that while we do not rule out external contributors from working on roadmapped issues, we will generally prefer to handle them ourselves unless they're not very time sensitive.
|
||||||
|
|
||||||
In the case of simple issues, a direct PR is okay. However, if you decide to work on an existing issue which doesn't seem trivial, **please ask us first**. This way we can try to estimate if it is a good fit for you and provide the correct direction on how to address it. In addition, note that while we do not rule out external contributors from working on roadmapped issues, we will generally prefer to handle them ourselves unless they're not very time sensitive.
|
|
||||||
|
|
||||||
If you'd like to propose a subjective change to one of the visual aspects of the game, or there is a bigger task you'd like to work on, but there is no corresponding issue or discussion thread yet for it, **please open a discussion or issue first** to avoid wasted effort. This in particular applies if you want to work on [one of the available designs from the osu! Figma master library](https://www.figma.com/file/VIkXMYNPMtQem2RJg9k2iQ/Master-Library).
|
If you'd like to propose a subjective change to one of the visual aspects of the game, or there is a bigger task you'd like to work on, but there is no corresponding issue or discussion thread yet for it, **please open a discussion or issue first** to avoid wasted effort. This in particular applies if you want to work on [one of the available designs from the osu! Figma master library](https://www.figma.com/file/VIkXMYNPMtQem2RJg9k2iQ/Master-Library).
|
||||||
|
|
||||||
|
|||||||
@@ -49,7 +49,7 @@
|
|||||||
<PackageProjectUrl>https://github.com/ppy/osu</PackageProjectUrl>
|
<PackageProjectUrl>https://github.com/ppy/osu</PackageProjectUrl>
|
||||||
<RepositoryUrl>https://github.com/ppy/osu</RepositoryUrl>
|
<RepositoryUrl>https://github.com/ppy/osu</RepositoryUrl>
|
||||||
<PackageReleaseNotes>Automated release.</PackageReleaseNotes>
|
<PackageReleaseNotes>Automated release.</PackageReleaseNotes>
|
||||||
<Company>ppy Pty Ltd</Company>
|
<Company>ppy Pty Ltd, jvnkosu! team</Company>
|
||||||
<Copyright>Copyright (c) 2025 ppy Pty Ltd</Copyright>
|
<Copyright>Copyright (c) 2025 ppy Pty Ltd</Copyright>
|
||||||
<PackageTags>osu game</PackageTags>
|
<PackageTags>osu game</PackageTags>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|||||||
19
MakeInstaller.ps1
Normal file
19
MakeInstaller.ps1
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
#!/usr/bin/env powershell
|
||||||
|
param (
|
||||||
|
[string]$Version,
|
||||||
|
[string]$BuildConfig = "Release"
|
||||||
|
)
|
||||||
|
|
||||||
|
if ($Version -eq "") {
|
||||||
|
Write-Host "Usage: .\MakeInstaller.ps1 <VERSION_NUMBER> [-BuildConfig <BUILD_CONFIG>]"
|
||||||
|
Write-Host "Example: .\MakeInstaller.ps1 2025.823.0 -BuildConfig Debug"
|
||||||
|
exit
|
||||||
|
}
|
||||||
|
|
||||||
|
$tmpPub = ".\pub"
|
||||||
|
if (-not (Test-Path -Path $tmpPub)) {
|
||||||
|
New-Item -ItemType Directory -path $tmpPub
|
||||||
|
}
|
||||||
|
|
||||||
|
dotnet publish -c $BuildConfig osu.Desktop --self-contained -r win-x64 -o $tmpPub -verbosity:m /p:Version=$Version
|
||||||
|
vpk pack --packId jvnkosu.Client --packTitle "jvnkosu!lazer" --packVersion $Version --packDir ./pub --mainExe="osu!.exe"
|
||||||
149
README.md
149
README.md
@@ -1,147 +1,40 @@
|
|||||||
<p align="center">
|
# jvnkosu! client
|
||||||
<img width="500" alt="osu! logo" src="assets/lazer.png">
|
|
||||||
</p>
|
|
||||||
|
|
||||||
# osu!
|
A free-to-win rhythm game based on osu!(lazer). Click is just a *rhythm* away!
|
||||||
|
|
||||||
[](https://github.com/ppy/osu/actions/workflows/ci.yml)
|
## Disclaimer
|
||||||
[](https://github.com/ppy/osu/releases/latest)
|
|
||||||
[](https://www.codefactor.io/repository/github/ppy/osu)
|
|
||||||
[](https://discord.gg/ppy)
|
|
||||||
[](https://crowdin.com/project/osu-web)
|
|
||||||
|
|
||||||
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).
|
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.
|
||||||
- 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!
|
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:
|
||||||
|
```
|
||||||
If you are just looking to give the game a whirl, you can grab the latest release for your platform:
|
git clone https://gitea.jvnko.boats/jvnkosu/client
|
||||||
|
|
||||||
### Latest release:
|
|
||||||
|
|
||||||
| [Windows 10+ (x64)](https://github.com/ppy/osu/releases/latest/download/install.exe) | macOS 12+ ([Intel](https://github.com/ppy/osu/releases/latest/download/osu.app.Intel.zip), [Apple Silicon](https://github.com/ppy/osu/releases/latest/download/osu.app.Apple.Silicon.zip)) | [Linux (x64)](https://github.com/ppy/osu/releases/latest/download/osu.AppImage) | [iOS 13.4+](https://osu.ppy.sh/home/testflight) | [Android 5+](https://github.com/ppy/osu/releases/latest/download/sh.ppy.osulazer.apk) |
|
|
||||||
|--------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| ------------- | ------------- | ------------- |
|
|
||||||
|
|
||||||
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
|
To **run** the project, switch to project's directory and run the following:
|
||||||
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
|
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).
|
To **compile**:
|
||||||
|
```
|
||||||
If the build fails, try to restore NuGet packages with `dotnet restore`.
|
dotnet build osu.Desktop
|
||||||
|
|
||||||
### 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:
|
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
|
### See the [original readme](README.original.md) for more info.
|
||||||
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.
|
|
||||||
147
README.original.md
Normal file
147
README.original.md
Normal file
@@ -0,0 +1,147 @@
|
|||||||
|
<p align="center">
|
||||||
|
<img width="500" alt="osu! logo" src="assets/lazer.png">
|
||||||
|
</p>
|
||||||
|
|
||||||
|
# osu!
|
||||||
|
|
||||||
|
[](https://github.com/ppy/osu/actions/workflows/ci.yml)
|
||||||
|
[](https://github.com/ppy/osu/releases/latest)
|
||||||
|
[](https://www.codefactor.io/repository/github/ppy/osu)
|
||||||
|
[](https://discord.gg/ppy)
|
||||||
|
[](https://crowdin.com/project/osu-web)
|
||||||
|
|
||||||
|
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:
|
||||||
|
|
||||||
|
### Latest release:
|
||||||
|
|
||||||
|
| [Windows 10+ (x64)](https://github.com/ppy/osu/releases/latest/download/install.exe) | macOS 12+ ([Intel](https://github.com/ppy/osu/releases/latest/download/osu.app.Intel.zip), [Apple Silicon](https://github.com/ppy/osu/releases/latest/download/osu.app.Apple.Silicon.zip)) | [Linux (x64)](https://github.com/ppy/osu/releases/latest/download/osu.AppImage) | [iOS 13.4+](https://osu.ppy.sh/home/testflight) | [Android 5+](https://github.com/ppy/osu/releases/latest/download/sh.ppy.osulazer.apk) |
|
||||||
|
|--------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| ------------- | ------------- | ------------- |
|
||||||
|
|
||||||
|
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.
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<PackageType>Template</PackageType>
|
<PackageType>Template</PackageType>
|
||||||
<PackageId>ppy.osu.Game.Templates</PackageId>
|
<PackageId>jvnkosu.Client.Templates</PackageId>
|
||||||
<Title>osu! templates</Title>
|
<Title>osu! templates</Title>
|
||||||
<Authors>ppy Pty Ltd</Authors>
|
<Authors>ppy Pty Ltd</Authors>
|
||||||
<PackageLicenseUrl>https://github.com/ppy/osu/blob/master/LICENCE</PackageLicenseUrl>
|
<PackageLicenseUrl>https://github.com/ppy/osu/blob/master/LICENCE</PackageLicenseUrl>
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
<EmbedAssembliesIntoApk>true</EmbedAssembliesIntoApk>
|
<EmbedAssembliesIntoApk>true</EmbedAssembliesIntoApk>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="ppy.osu.Framework.Android" Version="2025.1209.0" />
|
<PackageReference Include="ppy.osu.Framework.Android" Version="2026.303.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<!-- Fody does not handle Android build well, and warns when unchanged.
|
<!-- Fody does not handle Android build well, and warns when unchanged.
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="sh.ppy.osulazer" android:installLocation="auto">
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="boats.jvnko.osu.android" android:installLocation="auto">
|
||||||
<uses-sdk android:minSdkVersion="21" android:targetSdkVersion="34" />
|
<uses-sdk android:minSdkVersion="21" android:targetSdkVersion="34" />
|
||||||
<application android:allowBackup="true"
|
<application android:allowBackup="true"
|
||||||
android:supportsRtl="true"
|
android:supportsRtl="true"
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ namespace osu.Desktop
|
|||||||
{
|
{
|
||||||
internal partial class DiscordRichPresence : Component
|
internal partial class DiscordRichPresence : Component
|
||||||
{
|
{
|
||||||
private const string client_id = "1216669957799018608";
|
private const string client_id = "1440647613358800918";
|
||||||
|
|
||||||
private DiscordRpcClient client = null!;
|
private DiscordRpcClient client = null!;
|
||||||
|
|
||||||
|
|||||||
@@ -118,7 +118,7 @@ namespace osu.Desktop
|
|||||||
if (IsPackageManaged)
|
if (IsPackageManaged)
|
||||||
return new NoActionUpdateManager();
|
return new NoActionUpdateManager();
|
||||||
|
|
||||||
return new VelopackUpdateManager();
|
return new VelopackUpdateManager(); // yay
|
||||||
}
|
}
|
||||||
|
|
||||||
public override bool RestartAppWhenExited()
|
public override bool RestartAppWhenExited()
|
||||||
@@ -148,7 +148,13 @@ namespace osu.Desktop
|
|||||||
|
|
||||||
var iconStream = Assembly.GetExecutingAssembly().GetManifestResourceStream(GetType(), "lazer.ico");
|
var iconStream = Assembly.GetExecutingAssembly().GetManifestResourceStream(GetType(), "lazer.ico");
|
||||||
if (iconStream != null)
|
if (iconStream != null)
|
||||||
host.Window.SetIconFromStream(iconStream);
|
try
|
||||||
|
{
|
||||||
|
host.Window.SetIconFromStream(iconStream);
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
host.Window.Title = Name;
|
host.Window.Title = Name;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,9 +21,9 @@ namespace osu.Desktop
|
|||||||
public static class Program
|
public static class Program
|
||||||
{
|
{
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
private const string base_game_name = @"osu-development";
|
private const string base_game_name = @"jvnkosu-development";
|
||||||
#else
|
#else
|
||||||
private const string base_game_name = @"osu";
|
private const string base_game_name = @"jvnkosu";
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
private static LegacyTcpIpcProvider? legacyIpc;
|
private static LegacyTcpIpcProvider? legacyIpc;
|
||||||
@@ -44,7 +44,7 @@ namespace osu.Desktop
|
|||||||
|
|
||||||
// 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.
|
// 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/
|
// See https://www.mongodb.com/docs/realm/sdk/dotnet/compatibility/
|
||||||
if (windowsVersion.Major < 6 || (windowsVersion.Major == 6 && windowsVersion.Minor <= 2))
|
if (windowsVersion.Major < 6)
|
||||||
{
|
{
|
||||||
unsafe
|
unsafe
|
||||||
{
|
{
|
||||||
@@ -53,13 +53,26 @@ namespace osu.Desktop
|
|||||||
// We could also better detect compatibility mode if required:
|
// We could also better detect compatibility mode if required:
|
||||||
// https://stackoverflow.com/questions/10744651/how-i-can-detect-if-my-application-is-running-under-compatibility-mode#comment58183249_10744730
|
// https://stackoverflow.com/questions/10744651/how-i-can-detect-if-my-application-is-running-under-compatibility-mode#comment58183249_10744730
|
||||||
SDL3.SDL_ShowSimpleMessageBox(SDL_MessageBoxFlags.SDL_MESSAGEBOX_ERROR,
|
SDL3.SDL_ShowSimpleMessageBox(SDL_MessageBoxFlags.SDL_MESSAGEBOX_ERROR,
|
||||||
"Your operating system is too old to run osu!"u8,
|
"Your operating system is too old to run this game!"u8,
|
||||||
"This version of osu! requires at least Windows 8.1 to run.\n"u8
|
"This version of the game requires at least Windows 8.1 to run reliably.\n"u8
|
||||||
+ "Please upgrade your operating system or consider using an older version of osu!.\n\n"u8
|
+ "You may try to run it on Windows 8 or older, but it's not guaranteed to actually work.\n\n"u8
|
||||||
+ "If you are running a newer version of windows, please check you don't have \"Compatibility mode\" turned on for osu!"u8, null);
|
+ "Please upgrade your operating system or consider using an older game version.\n\n"u8
|
||||||
|
+ "If you are running a newer version of Windows, please check you don't have \"Compatibility mode\" turned on for the game's executable."u8, null);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (windowsVersion.Major == 6 && windowsVersion.Minor <= 2)
|
||||||
|
{
|
||||||
|
unsafe
|
||||||
|
{
|
||||||
|
SDL3.SDL_ShowSimpleMessageBox(SDL_MessageBoxFlags.SDL_MESSAGEBOX_WARNING,
|
||||||
|
"Your operating system is too old to run this game!"u8,
|
||||||
|
"While the version of Windows you're using may be able to launch it, it's likely to work unreliably and crash.\n"u8
|
||||||
|
+ "Please upgrade your operating system or consider using an older game version.\n\n"u8
|
||||||
|
+ "If you are running a newer version of Windows, please check you don't have \"Compatibility mode\" turned on for the game's executable."u8, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// NVIDIA profiles are based on the executable name of a process.
|
// NVIDIA profiles are based on the executable name of a process.
|
||||||
@@ -208,9 +221,10 @@ namespace osu.Desktop
|
|||||||
[SupportedOSPlatform("windows")]
|
[SupportedOSPlatform("windows")]
|
||||||
private static void configureWindows(VelopackApp app)
|
private static void configureWindows(VelopackApp app)
|
||||||
{
|
{
|
||||||
app.OnFirstRun(_ => WindowsAssociationManager.InstallAssociations());
|
// we do not want associations here, as that breaks official lazer's associations
|
||||||
app.OnAfterUpdateFastCallback(_ => WindowsAssociationManager.UpdateAssociations());
|
// app.OnFirstRun(_ => WindowsAssociationManager.InstallAssociations());
|
||||||
app.OnBeforeUninstallFastCallback(_ => WindowsAssociationManager.UninstallAssociations());
|
// app.OnAfterUpdateFastCallback(_ => WindowsAssociationManager.UpdateAssociations());
|
||||||
|
// app.OnBeforeUninstallFastCallback(_ => WindowsAssociationManager.UninstallAssociations());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ using osu.Framework.Allocation;
|
|||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Sprites;
|
using osu.Framework.Graphics.Sprites;
|
||||||
using osu.Game.Graphics;
|
using osu.Game.Graphics;
|
||||||
|
using osu.Game.Localisation;
|
||||||
using osu.Game.Overlays;
|
using osu.Game.Overlays;
|
||||||
using osu.Game.Overlays.Notifications;
|
using osu.Game.Overlays.Notifications;
|
||||||
|
|
||||||
@@ -32,7 +33,7 @@ namespace osu.Desktop.Security
|
|||||||
{
|
{
|
||||||
public ElevatedPrivilegesNotification()
|
public ElevatedPrivilegesNotification()
|
||||||
{
|
{
|
||||||
Text = $"Running osu! as {(RuntimeInfo.IsUnix ? "root" : "administrator")} does not improve performance, may break integrations and poses a security risk. Please run the game as a normal user.";
|
Text = NotificationsStrings.ElevatedPrivileges(RuntimeInfo.IsUnix ? "root" : "Administrator");
|
||||||
}
|
}
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ namespace osu.Desktop.Updater
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
IUpdateSource updateSource = new GithubSource(@"https://github.com/ppy/osu", null, ReleaseStream.Value == Game.Configuration.ReleaseStream.Tachyon);
|
IUpdateSource updateSource = new GiteaSource(@"https://gitea.jvnko.boats/jvnkosu/client", null, ReleaseStream.Value == Game.Configuration.ReleaseStream.Tachyon);
|
||||||
Velopack.UpdateManager updateManager = new Velopack.UpdateManager(updateSource, new UpdateOptions
|
Velopack.UpdateManager updateManager = new Velopack.UpdateManager(updateSource, new UpdateOptions
|
||||||
{
|
{
|
||||||
AllowVersionDowngrade = true
|
AllowVersionDowngrade = true
|
||||||
|
|||||||
@@ -53,8 +53,8 @@ namespace osu.Desktop.Windows
|
|||||||
|
|
||||||
private static readonly UriAssociation[] uri_associations =
|
private static readonly UriAssociation[] uri_associations =
|
||||||
{
|
{
|
||||||
new UriAssociation(@"osu", WindowsAssociationManagerStrings.OsuProtocol, Icons.Lazer),
|
new UriAssociation(@"jvnkosu", WindowsAssociationManagerStrings.OsuProtocol, Icons.Lazer),
|
||||||
new UriAssociation(@"osump", WindowsAssociationManagerStrings.OsuMultiplayer, Icons.Lazer),
|
new UriAssociation(@"jvnkosump", WindowsAssociationManagerStrings.OsuMultiplayer, Icons.Lazer),
|
||||||
};
|
};
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
Binary file not shown.
|
Before Width: | Height: | Size: 75 KiB After Width: | Height: | Size: 401 KiB |
@@ -3,11 +3,11 @@
|
|||||||
<TargetFramework>net8.0</TargetFramework>
|
<TargetFramework>net8.0</TargetFramework>
|
||||||
<OutputType>WinExe</OutputType>
|
<OutputType>WinExe</OutputType>
|
||||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||||
<Description>A free-to-win rhythm game. Rhythm is just a *click* away!</Description>
|
<Description>A free-to-win rhythm game based on osu!(lazer). Click is just a *rhythm* away!</Description>
|
||||||
<AssemblyName>osu!</AssemblyName>
|
<AssemblyName>osu!</AssemblyName>
|
||||||
<AssemblyTitle>osu!(lazer)</AssemblyTitle>
|
<AssemblyTitle>jvnkosu!</AssemblyTitle>
|
||||||
<Title>osu!</Title>
|
<Title>jvnkosu!</Title>
|
||||||
<Product>osu!(lazer)</Product>
|
<Product>jvnkosu!</Product>
|
||||||
<ApplicationIcon>lazer.ico</ApplicationIcon>
|
<ApplicationIcon>lazer.ico</ApplicationIcon>
|
||||||
<Version>0.0.0</Version>
|
<Version>0.0.0</Version>
|
||||||
<FileVersion>0.0.0</FileVersion>
|
<FileVersion>0.0.0</FileVersion>
|
||||||
|
|||||||
@@ -3,16 +3,19 @@
|
|||||||
<metadata>
|
<metadata>
|
||||||
<id>osulazer</id>
|
<id>osulazer</id>
|
||||||
<version>0.0.0</version>
|
<version>0.0.0</version>
|
||||||
<title>osu!</title>
|
<title>jvnkosu!</title>
|
||||||
<authors>ppy Pty Ltd</authors>
|
<authors>ppy Pty Ltd., jvnkosu! team</authors>
|
||||||
<owners>Dean Herbert</owners>
|
<owners>Dean Herbert</owners>
|
||||||
<projectUrl>https://osu.ppy.sh/</projectUrl>
|
<projectUrl>https://osu.jvnko.boats/</projectUrl>
|
||||||
<iconUrl>https://github.com/ppy/osu/blob/master/assets/lazer-nuget.png?raw=true</iconUrl>
|
<iconUrl>https://github.com/ppy/osu/blob/master/assets/lazer-nuget.png?raw=true</iconUrl>
|
||||||
<icon>icon.png</icon>
|
<icon>icon.png</icon>
|
||||||
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
||||||
<description>A free-to-win rhythm game. Rhythm is just a *click* away!</description>
|
<description>A free-to-win rhythm game based on osu!(lazer). Click is just a *rhythm* away!</description>
|
||||||
<releaseNotes>testing</releaseNotes>
|
<releaseNotes>testing</releaseNotes>
|
||||||
<copyright>Copyright (c) 2025 ppy Pty Ltd</copyright>
|
<copyright>
|
||||||
|
Copyright (c) 2025 ppy Pty Ltd
|
||||||
|
Copyright (c) 2025 jvnkosu! team
|
||||||
|
</copyright>
|
||||||
<language>en-AU</language>
|
<language>en-AU</language>
|
||||||
</metadata>
|
</metadata>
|
||||||
<files>
|
<files>
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ using BenchmarkDotNet.Attributes;
|
|||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Rulesets;
|
using osu.Game.Rulesets;
|
||||||
using osu.Game.Screens.Select;
|
using osu.Game.Screens.Select;
|
||||||
using osu.Game.Screens.Select.Carousel;
|
using osu.Game.Tests.NonVisual.Filtering;
|
||||||
|
|
||||||
namespace osu.Game.Benchmarks
|
namespace osu.Game.Benchmarks
|
||||||
{
|
{
|
||||||
@@ -42,7 +42,7 @@ namespace osu.Game.Benchmarks
|
|||||||
Status = BeatmapOnlineStatus.Loved
|
Status = BeatmapOnlineStatus.Loved
|
||||||
};
|
};
|
||||||
|
|
||||||
private CarouselBeatmap carouselBeatmap = null!;
|
private FilterMatchingTest.CarouselBeatmap carouselBeatmap = null!;
|
||||||
private FilterCriteria criteria1 = null!;
|
private FilterCriteria criteria1 = null!;
|
||||||
private FilterCriteria criteria2 = null!;
|
private FilterCriteria criteria2 = null!;
|
||||||
private FilterCriteria criteria3 = null!;
|
private FilterCriteria criteria3 = null!;
|
||||||
@@ -55,7 +55,7 @@ namespace osu.Game.Benchmarks
|
|||||||
var beatmap = getExampleBeatmap();
|
var beatmap = getExampleBeatmap();
|
||||||
beatmap.OnlineID = 20201010;
|
beatmap.OnlineID = 20201010;
|
||||||
beatmap.BeatmapSet = new BeatmapSetInfo { OnlineID = 1535 };
|
beatmap.BeatmapSet = new BeatmapSetInfo { OnlineID = 1535 };
|
||||||
carouselBeatmap = new CarouselBeatmap(beatmap);
|
carouselBeatmap = new FilterMatchingTest.CarouselBeatmap(beatmap);
|
||||||
criteria1 = new FilterCriteria();
|
criteria1 = new FilterCriteria();
|
||||||
criteria2 = new FilterCriteria
|
criteria2 = new FilterCriteria
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -35,11 +35,9 @@
|
|||||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||||
</array>
|
</array>
|
||||||
<key>XSAppIconAssets</key>
|
|
||||||
<string>Assets.xcassets/AppIcon.appiconset</string>
|
|
||||||
<key>UIApplicationSupportsIndirectInputEvents</key>
|
<key>UIApplicationSupportsIndirectInputEvents</key>
|
||||||
<true/>
|
<true/>
|
||||||
<key>CADisableMinimumFrameDurationOnPhone</key>
|
<key>CADisableMinimumFrameDurationOnPhone</key>
|
||||||
<true/>
|
<true/>
|
||||||
</dict>
|
</dict>
|
||||||
</plist>
|
</plist>
|
||||||
|
|||||||
@@ -176,15 +176,20 @@ namespace osu.Game.Rulesets.Catch
|
|||||||
|
|
||||||
public override Drawable CreateIcon() => new SpriteIcon { Icon = OsuIcon.RulesetCatch };
|
public override Drawable CreateIcon() => new SpriteIcon { Icon = OsuIcon.RulesetCatch };
|
||||||
|
|
||||||
protected override IEnumerable<HitResult> GetValidHitResults()
|
public override IEnumerable<HitResult> GetValidHitResults()
|
||||||
{
|
{
|
||||||
return new[]
|
return new[]
|
||||||
{
|
{
|
||||||
HitResult.Great,
|
HitResult.Great,
|
||||||
|
HitResult.Miss,
|
||||||
|
|
||||||
HitResult.LargeTickHit,
|
HitResult.LargeTickHit,
|
||||||
|
HitResult.LargeTickMiss,
|
||||||
HitResult.SmallTickHit,
|
HitResult.SmallTickHit,
|
||||||
|
HitResult.SmallTickMiss,
|
||||||
HitResult.LargeBonus,
|
HitResult.LargeBonus,
|
||||||
|
HitResult.IgnoreHit,
|
||||||
|
HitResult.IgnoreMiss,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -300,7 +305,7 @@ namespace osu.Game.Rulesets.Catch
|
|||||||
Description = "Affects how early fruits fade in on the screen.",
|
Description = "Affects how early fruits fade in on the screen.",
|
||||||
AdditionalMetrics =
|
AdditionalMetrics =
|
||||||
[
|
[
|
||||||
new RulesetBeatmapAttribute.AdditionalMetric("Fade-in time", LocalisableString.Interpolate($@"{IBeatmapDifficultyInfo.DifficultyRange(effectiveDifficulty.ApproachRate, CatchHitObject.PREEMPT_RANGE):#,0.##} ms"))
|
new RulesetBeatmapAttribute.AdditionalMetric("Fade-in time", LocalisableString.Interpolate($@"{IBeatmapDifficultyInfo.DifficultyRangeInt(effectiveDifficulty.ApproachRate, CatchHitObject.PREEMPT_RANGE):#,0.##} ms"))
|
||||||
]
|
]
|
||||||
};
|
};
|
||||||
yield return new RulesetBeatmapAttribute(SongSelectStrings.HPDrain, @"HP", originalDifficulty.DrainRate, effectiveDifficulty.DrainRate, 10)
|
yield return new RulesetBeatmapAttribute(SongSelectStrings.HPDrain, @"HP", originalDifficulty.DrainRate, effectiveDifficulty.DrainRate, 10)
|
||||||
|
|||||||
@@ -150,7 +150,7 @@ namespace osu.Game.Rulesets.Catch.Objects
|
|||||||
{
|
{
|
||||||
base.ApplyDefaultsToSelf(controlPointInfo, difficulty);
|
base.ApplyDefaultsToSelf(controlPointInfo, difficulty);
|
||||||
|
|
||||||
TimePreempt = (float)IBeatmapDifficultyInfo.DifficultyRange(difficulty.ApproachRate, PREEMPT_RANGE);
|
TimePreempt = IBeatmapDifficultyInfo.DifficultyRangeInt(difficulty.ApproachRate, PREEMPT_RANGE);
|
||||||
|
|
||||||
Scale = LegacyRulesetExtensions.CalculateScaleFromCircleSize(difficulty.CircleSize);
|
Scale = LegacyRulesetExtensions.CalculateScaleFromCircleSize(difficulty.CircleSize);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
<PropertyGroup Label="Nuget">
|
<PropertyGroup Label="Nuget">
|
||||||
<Title>osu!catch (ruleset)</Title>
|
<Title>osu!catch (ruleset)</Title>
|
||||||
<PackageId>ppy.osu.Game.Rulesets.Catch</PackageId>
|
<PackageId>jvnkosu.Client.Rulesets.Catch</PackageId>
|
||||||
<IsPackable>true</IsPackable>
|
<IsPackable>true</IsPackable>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
|
|||||||
@@ -35,11 +35,9 @@
|
|||||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||||
</array>
|
</array>
|
||||||
<key>XSAppIconAssets</key>
|
|
||||||
<string>Assets.xcassets/AppIcon.appiconset</string>
|
|
||||||
<key>UIApplicationSupportsIndirectInputEvents</key>
|
<key>UIApplicationSupportsIndirectInputEvents</key>
|
||||||
<true/>
|
<true/>
|
||||||
<key>CADisableMinimumFrameDurationOnPhone</key>
|
<key>CADisableMinimumFrameDurationOnPhone</key>
|
||||||
<true/>
|
<true/>
|
||||||
</dict>
|
</dict>
|
||||||
</plist>
|
</plist>
|
||||||
|
|||||||
@@ -383,7 +383,7 @@ namespace osu.Game.Rulesets.Mania
|
|||||||
return (PlayfieldType)Enum.GetValues(typeof(PlayfieldType)).Cast<int>().OrderDescending().First(v => variant >= v);
|
return (PlayfieldType)Enum.GetValues(typeof(PlayfieldType)).Cast<int>().OrderDescending().First(v => variant >= v);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override IEnumerable<HitResult> GetValidHitResults()
|
public override IEnumerable<HitResult> GetValidHitResults()
|
||||||
{
|
{
|
||||||
return new[]
|
return new[]
|
||||||
{
|
{
|
||||||
@@ -392,9 +392,11 @@ namespace osu.Game.Rulesets.Mania
|
|||||||
HitResult.Good,
|
HitResult.Good,
|
||||||
HitResult.Ok,
|
HitResult.Ok,
|
||||||
HitResult.Meh,
|
HitResult.Meh,
|
||||||
|
HitResult.Miss,
|
||||||
|
|
||||||
// HitResult.SmallBonus is used for awarding perfect bonus score but is not included here as
|
HitResult.IgnoreHit,
|
||||||
// it would be a bit redundant to show this to the user.
|
HitResult.ComboBreak,
|
||||||
|
HitResult.IgnoreMiss,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ using osu.Framework;
|
|||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Localisation;
|
using osu.Framework.Localisation;
|
||||||
using osu.Game.Graphics.UserInterface;
|
using osu.Game.Graphics.UserInterfaceV2;
|
||||||
using osu.Game.Localisation;
|
using osu.Game.Localisation;
|
||||||
using osu.Game.Overlays.Settings;
|
using osu.Game.Overlays.Settings;
|
||||||
using osu.Game.Rulesets.Mania.Configuration;
|
using osu.Game.Rulesets.Mania.Configuration;
|
||||||
@@ -31,47 +31,45 @@ namespace osu.Game.Rulesets.Mania
|
|||||||
|
|
||||||
Children = new Drawable[]
|
Children = new Drawable[]
|
||||||
{
|
{
|
||||||
new SettingsEnumDropdown<ManiaScrollingDirection>
|
new SettingsItemV2(new FormEnumDropdown<ManiaScrollingDirection>
|
||||||
{
|
{
|
||||||
LabelText = RulesetSettingsStrings.ScrollingDirection,
|
Caption = RulesetSettingsStrings.ScrollingDirection,
|
||||||
Current = config.GetBindable<ManiaScrollingDirection>(ManiaRulesetSetting.ScrollDirection)
|
Current = config.GetBindable<ManiaScrollingDirection>(ManiaRulesetSetting.ScrollDirection)
|
||||||
},
|
}),
|
||||||
new SettingsSlider<double, ManiaScrollSlider>
|
new SettingsItemV2(new FormSliderBar<double>
|
||||||
{
|
{
|
||||||
LabelText = RulesetSettingsStrings.ScrollSpeed,
|
Caption = RulesetSettingsStrings.ScrollSpeed,
|
||||||
Current = config.GetBindable<double>(ManiaRulesetSetting.ScrollSpeed),
|
Current = config.GetBindable<double>(ManiaRulesetSetting.ScrollSpeed),
|
||||||
KeyboardStep = 1
|
KeyboardStep = 1,
|
||||||
},
|
LabelFormat = v => RulesetSettingsStrings.ScrollSpeedTooltip((int)DrawableManiaRuleset.ComputeScrollTime(v), v),
|
||||||
new SettingsCheckbox
|
}),
|
||||||
|
new SettingsItemV2(new FormCheckBox
|
||||||
|
{
|
||||||
|
Caption = RulesetSettingsStrings.TimingBasedColouring,
|
||||||
|
Current = config.GetBindable<bool>(ManiaRulesetSetting.TimingBasedNoteColouring),
|
||||||
|
})
|
||||||
{
|
{
|
||||||
Keywords = new[] { "color" },
|
Keywords = new[] { "color" },
|
||||||
LabelText = RulesetSettingsStrings.TimingBasedColouring,
|
|
||||||
Current = config.GetBindable<bool>(ManiaRulesetSetting.TimingBasedNoteColouring),
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
Add(new SettingsCheckbox
|
Add(new SettingsItemV2(new FormCheckBox
|
||||||
{
|
{
|
||||||
LabelText = RulesetSettingsStrings.TouchOverlay,
|
Caption = RulesetSettingsStrings.TouchOverlay,
|
||||||
Current = config.GetBindable<bool>(ManiaRulesetSetting.TouchOverlay)
|
Current = config.GetBindable<bool>(ManiaRulesetSetting.TouchOverlay)
|
||||||
});
|
}));
|
||||||
|
|
||||||
if (RuntimeInfo.IsMobile)
|
if (RuntimeInfo.IsMobile)
|
||||||
{
|
{
|
||||||
Add(new SettingsEnumDropdown<ManiaMobileLayout>
|
Add(new SettingsItemV2(new FormEnumDropdown<ManiaMobileLayout>
|
||||||
{
|
{
|
||||||
LabelText = RulesetSettingsStrings.MobileLayout,
|
Caption = RulesetSettingsStrings.MobileLayout,
|
||||||
Current = config.GetBindable<ManiaMobileLayout>(ManiaRulesetSetting.MobileLayout),
|
Current = config.GetBindable<ManiaMobileLayout>(ManiaRulesetSetting.MobileLayout),
|
||||||
#pragma warning disable CS0618 // Type or member is obsolete
|
#pragma warning disable CS0618 // Type or member is obsolete
|
||||||
Items = Enum.GetValues<ManiaMobileLayout>().Where(l => l != ManiaMobileLayout.LandscapeWithOverlay),
|
Items = Enum.GetValues<ManiaMobileLayout>().Where(l => l != ManiaMobileLayout.LandscapeWithOverlay),
|
||||||
#pragma warning restore CS0618 // Type or member is obsolete
|
#pragma warning restore CS0618 // Type or member is obsolete
|
||||||
});
|
}));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private partial class ManiaScrollSlider : RoundedSliderBar<double>
|
|
||||||
{
|
|
||||||
public override LocalisableString TooltipText => RulesetSettingsStrings.ScrollSpeedTooltip((int)DrawableManiaRuleset.ComputeScrollTime(Current.Value), Current.Value);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,8 +14,8 @@ namespace osu.Game.Rulesets.Mania.Mods
|
|||||||
public override string Acronym => Name;
|
public override string Acronym => Name;
|
||||||
public abstract int KeyCount { get; }
|
public abstract int KeyCount { get; }
|
||||||
public override ModType Type => ModType.Conversion;
|
public override ModType Type => ModType.Conversion;
|
||||||
public override double ScoreMultiplier => 0.9;
|
public override double ScoreMultiplier => 1;
|
||||||
public override bool Ranked => UsesDefaultConfiguration;
|
public override bool Ranked => true;
|
||||||
|
|
||||||
public void ApplyToBeatmapConverter(IBeatmapConverter beatmapConverter)
|
public void ApplyToBeatmapConverter(IBeatmapConverter beatmapConverter)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ namespace osu.Game.Rulesets.Mania.Mods
|
|||||||
typeof(ManiaModFadeIn)
|
typeof(ManiaModFadeIn)
|
||||||
}).ToArray();
|
}).ToArray();
|
||||||
|
|
||||||
public override bool Ranked => false;
|
public override bool Ranked => true;
|
||||||
|
|
||||||
public override bool ValidForFreestyleAsRequiredMod => false;
|
public override bool ValidForFreestyleAsRequiredMod => false;
|
||||||
|
|
||||||
|
|||||||
@@ -13,8 +13,13 @@ namespace osu.Game.Rulesets.Mania.Mods
|
|||||||
MinValue = 0,
|
MinValue = 0,
|
||||||
MaxValue = 10,
|
MaxValue = 10,
|
||||||
// Use larger extended limits for mania to include OD values that occur with EZ or HR enabled
|
// Use larger extended limits for mania to include OD values that occur with EZ or HR enabled
|
||||||
|
#if !DEBUG
|
||||||
ExtendedMaxValue = 15,
|
ExtendedMaxValue = 15,
|
||||||
ExtendedMinValue = -15,
|
ExtendedMinValue = -15,
|
||||||
|
#else
|
||||||
|
ExtendedMinValue = -250,
|
||||||
|
ExtendedMaxValue = 50,
|
||||||
|
#endif
|
||||||
ReadCurrentFromDifficulty = diff => diff.OverallDifficulty,
|
ReadCurrentFromDifficulty = diff => diff.OverallDifficulty,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ namespace osu.Game.Rulesets.Mania.Mods
|
|||||||
public class ManiaModHardRock : ModHardRock, IApplicableToHitObject
|
public class ManiaModHardRock : ModHardRock, IApplicableToHitObject
|
||||||
{
|
{
|
||||||
public override double ScoreMultiplier => 1;
|
public override double ScoreMultiplier => 1;
|
||||||
public override bool Ranked => false;
|
public override bool Ranked => true;
|
||||||
|
|
||||||
public const double HIT_WINDOW_DIFFICULTY_MULTIPLIER = 1.4;
|
public const double HIT_WINDOW_DIFFICULTY_MULTIPLIER = 1.4;
|
||||||
|
|
||||||
|
|||||||
@@ -14,6 +14,5 @@ namespace osu.Game.Rulesets.Mania.Mods
|
|||||||
public override string Acronym => "1K";
|
public override string Acronym => "1K";
|
||||||
public override IconUsage? Icon => OsuIcon.ModOneKey;
|
public override IconUsage? Icon => OsuIcon.ModOneKey;
|
||||||
public override LocalisableString Description => @"Play with one key.";
|
public override LocalisableString Description => @"Play with one key.";
|
||||||
public override bool Ranked => false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,6 +14,5 @@ namespace osu.Game.Rulesets.Mania.Mods
|
|||||||
public override string Acronym => "10K";
|
public override string Acronym => "10K";
|
||||||
public override IconUsage? Icon => OsuIcon.ModTenKeys;
|
public override IconUsage? Icon => OsuIcon.ModTenKeys;
|
||||||
public override LocalisableString Description => @"Play with ten keys.";
|
public override LocalisableString Description => @"Play with ten keys.";
|
||||||
public override bool Ranked => false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,6 +14,5 @@ namespace osu.Game.Rulesets.Mania.Mods
|
|||||||
public override string Acronym => "2K";
|
public override string Acronym => "2K";
|
||||||
public override IconUsage? Icon => OsuIcon.ModTwoKeys;
|
public override IconUsage? Icon => OsuIcon.ModTwoKeys;
|
||||||
public override LocalisableString Description => @"Play with two keys.";
|
public override LocalisableString Description => @"Play with two keys.";
|
||||||
public override bool Ranked => false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,6 +14,5 @@ namespace osu.Game.Rulesets.Mania.Mods
|
|||||||
public override string Acronym => "3K";
|
public override string Acronym => "3K";
|
||||||
public override IconUsage? Icon => OsuIcon.ModThreeKeys;
|
public override IconUsage? Icon => OsuIcon.ModThreeKeys;
|
||||||
public override LocalisableString Description => @"Play with three keys.";
|
public override LocalisableString Description => @"Play with three keys.";
|
||||||
public override bool Ranked => false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ namespace osu.Game.Rulesets.Mania.Mods
|
|||||||
public class ManiaModMirror : ModMirror, IApplicableToBeatmap
|
public class ManiaModMirror : ModMirror, IApplicableToBeatmap
|
||||||
{
|
{
|
||||||
public override LocalisableString Description => "Notes are flipped horizontally.";
|
public override LocalisableString Description => "Notes are flipped horizontally.";
|
||||||
public override bool Ranked => UsesDefaultConfiguration;
|
public override bool Ranked => true;
|
||||||
|
|
||||||
public void ApplyToBeatmap(IBeatmap beatmap)
|
public void ApplyToBeatmap(IBeatmap beatmap)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -154,7 +154,7 @@ namespace osu.Game.Rulesets.Mania.UI
|
|||||||
|
|
||||||
var hitWindows = new ManiaHitWindows();
|
var hitWindows = new ManiaHitWindows();
|
||||||
|
|
||||||
AddInternal(judgementPooler = new JudgementPooler<DrawableManiaJudgement>(Enum.GetValues<HitResult>().Where(r => hitWindows.IsHitResultAllowed(r))));
|
AddInternal(judgementPooler = new JudgementPooler<DrawableManiaJudgement>(Enum.GetValues<HitResult>().Where(hitWindows.IsHitResultAllowed)));
|
||||||
|
|
||||||
RegisterPool<BarLine, DrawableBarLine>(50, 200);
|
RegisterPool<BarLine, DrawableBarLine>(50, 200);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
<PropertyGroup Label="Nuget">
|
<PropertyGroup Label="Nuget">
|
||||||
<Title>osu!mania (ruleset)</Title>
|
<Title>osu!mania (ruleset)</Title>
|
||||||
<PackageId>ppy.osu.Game.Rulesets.Mania</PackageId>
|
<PackageId>jvnkosu.Client.Rulesets.Mania</PackageId>
|
||||||
<IsPackable>true</IsPackable>
|
<IsPackable>true</IsPackable>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
|
|||||||
@@ -35,11 +35,9 @@
|
|||||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||||
</array>
|
</array>
|
||||||
<key>XSAppIconAssets</key>
|
|
||||||
<string>Assets.xcassets/AppIcon.appiconset</string>
|
|
||||||
<key>UIApplicationSupportsIndirectInputEvents</key>
|
<key>UIApplicationSupportsIndirectInputEvents</key>
|
||||||
<true/>
|
<true/>
|
||||||
<key>CADisableMinimumFrameDurationOnPhone</key>
|
<key>CADisableMinimumFrameDurationOnPhone</key>
|
||||||
<true/>
|
<true/>
|
||||||
</dict>
|
</dict>
|
||||||
</plist>
|
</plist>
|
||||||
|
|||||||
@@ -3,10 +3,13 @@
|
|||||||
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
|
using osu.Framework.Testing;
|
||||||
using osu.Framework.Utils;
|
using osu.Framework.Utils;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Rulesets.Objects;
|
using osu.Game.Rulesets.Objects;
|
||||||
using osu.Game.Rulesets.Objects.Types;
|
using osu.Game.Rulesets.Objects.Types;
|
||||||
|
using osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders;
|
||||||
|
using osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components;
|
||||||
using osu.Game.Rulesets.Osu.Objects;
|
using osu.Game.Rulesets.Osu.Objects;
|
||||||
using osu.Game.Rulesets.Osu.UI;
|
using osu.Game.Rulesets.Osu.UI;
|
||||||
using osu.Game.Tests.Beatmaps;
|
using osu.Game.Tests.Beatmaps;
|
||||||
@@ -30,6 +33,16 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor
|
|||||||
PathType.LINEAR,
|
PathType.LINEAR,
|
||||||
new Vector2(100, 0),
|
new Vector2(100, 0),
|
||||||
new Vector2(100, 100)
|
new Vector2(100, 100)
|
||||||
|
),
|
||||||
|
createPathSegment(
|
||||||
|
PathType.PERFECT_CURVE,
|
||||||
|
new Vector2(100.009f, -50.0009f),
|
||||||
|
new Vector2(200.0089f, -100)
|
||||||
|
),
|
||||||
|
createPathSegment(
|
||||||
|
PathType.PERFECT_CURVE,
|
||||||
|
new Vector2(25, -50),
|
||||||
|
new Vector2(100, 75)
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -48,9 +61,13 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor
|
|||||||
|
|
||||||
[TestCase(0, 250)]
|
[TestCase(0, 250)]
|
||||||
[TestCase(0, 200)]
|
[TestCase(0, 200)]
|
||||||
[TestCase(1, 120)]
|
[TestCase(1, 120, false, false)]
|
||||||
[TestCase(1, 80)]
|
[TestCase(1, 80, false, false)]
|
||||||
public void TestSliderReversal(int pathIndex, double length)
|
[TestCase(2, 250)]
|
||||||
|
[TestCase(2, 190)]
|
||||||
|
[TestCase(3, 250)]
|
||||||
|
[TestCase(3, 190)]
|
||||||
|
public void TestSliderReversal(int pathIndex, double length, bool assertEqualDistances = true, bool assertSliderReduction = true)
|
||||||
{
|
{
|
||||||
var controlPoints = paths[pathIndex];
|
var controlPoints = paths[pathIndex];
|
||||||
|
|
||||||
@@ -90,6 +107,215 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor
|
|||||||
InputManager.ReleaseKey(Key.LControl);
|
InputManager.ReleaseKey(Key.LControl);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (pathIndex == 2)
|
||||||
|
{
|
||||||
|
AddRepeatStep("Reverse slider again", () =>
|
||||||
|
{
|
||||||
|
InputManager.PressKey(Key.LControl);
|
||||||
|
InputManager.Key(Key.G);
|
||||||
|
InputManager.ReleaseKey(Key.LControl);
|
||||||
|
}, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (assertEqualDistances)
|
||||||
|
{
|
||||||
|
AddAssert("Middle control point has the same distance from start to end", () =>
|
||||||
|
{
|
||||||
|
var pathControlPoints = selectedSlider.Path.ControlPoints;
|
||||||
|
float middleToStart = Vector2.Distance(pathControlPoints[^2].Position, pathControlPoints[0].Position);
|
||||||
|
float middleToEnd = Vector2.Distance(pathControlPoints[^2].Position, pathControlPoints[^1].Position);
|
||||||
|
|
||||||
|
return Precision.AlmostEquals(middleToStart, middleToEnd, 1f);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
AddAssert("Middle control point is not at start or end", () =>
|
||||||
|
Vector2.Distance(selectedSlider.Path.ControlPoints[^2].Position, oldStartPos) > 1 &&
|
||||||
|
Vector2.Distance(selectedSlider.Path.ControlPoints[^2].Position, oldEndPos) > 1
|
||||||
|
);
|
||||||
|
|
||||||
|
AddAssert("Slider has correct length", () =>
|
||||||
|
Precision.AlmostEquals(selectedSlider.Path.Distance, oldDistance));
|
||||||
|
|
||||||
|
AddAssert("Slider has correct start position", () =>
|
||||||
|
Vector2.Distance(selectedSlider.Position, oldEndPos) < 1);
|
||||||
|
|
||||||
|
AddAssert("Slider has correct end position", () =>
|
||||||
|
Vector2.Distance(selectedSlider.EndPosition, oldStartPos) < 1);
|
||||||
|
|
||||||
|
AddAssert("Control points have correct types", () =>
|
||||||
|
{
|
||||||
|
var newControlPointTypes = selectedSlider.Path.ControlPoints.Select(p => p.Type).ToArray();
|
||||||
|
|
||||||
|
return oldControlPointTypes.Take(newControlPointTypes.Length).SequenceEqual(newControlPointTypes);
|
||||||
|
});
|
||||||
|
|
||||||
|
if (assertSliderReduction)
|
||||||
|
{
|
||||||
|
AddStep("Move to marker", () =>
|
||||||
|
{
|
||||||
|
var marker = this.ChildrenOfType<SliderEndDragMarker>().Single();
|
||||||
|
var markerPos = (marker.ScreenSpaceDrawQuad.TopRight + marker.ScreenSpaceDrawQuad.BottomRight) / 2;
|
||||||
|
// sometimes the cursor may miss the marker's hitbox so we
|
||||||
|
// add a little offset here to be sure it lands in a clickable position.
|
||||||
|
var position = new Vector2(markerPos.X + 2f, markerPos.Y);
|
||||||
|
InputManager.MoveMouseTo(position);
|
||||||
|
});
|
||||||
|
AddStep("Click", () => InputManager.PressButton(MouseButton.Left));
|
||||||
|
AddStep("Reduce slider", () =>
|
||||||
|
{
|
||||||
|
var middleControlPoint = this.ChildrenOfType<PathControlPointPiece<Slider>>().ToArray()[^2];
|
||||||
|
InputManager.MoveMouseTo(middleControlPoint);
|
||||||
|
});
|
||||||
|
AddStep("Release click", () => InputManager.ReleaseButton(MouseButton.Left));
|
||||||
|
|
||||||
|
AddStep("Save half slider info", () =>
|
||||||
|
{
|
||||||
|
oldStartPos = selectedSlider.Position;
|
||||||
|
oldEndPos = selectedSlider.EndPosition;
|
||||||
|
oldDistance = selectedSlider.Path.Distance;
|
||||||
|
});
|
||||||
|
|
||||||
|
AddStep("Reverse slider", () =>
|
||||||
|
{
|
||||||
|
InputManager.PressKey(Key.LControl);
|
||||||
|
InputManager.Key(Key.G);
|
||||||
|
InputManager.ReleaseKey(Key.LControl);
|
||||||
|
});
|
||||||
|
|
||||||
|
AddAssert("Middle control point has the same distance from start to end", () =>
|
||||||
|
{
|
||||||
|
var pathControlPoints = selectedSlider.Path.ControlPoints;
|
||||||
|
float middleToStart = Vector2.Distance(pathControlPoints[^2].Position, pathControlPoints[0].Position);
|
||||||
|
float middleToEnd = Vector2.Distance(pathControlPoints[^2].Position, pathControlPoints[^1].Position);
|
||||||
|
|
||||||
|
return Precision.AlmostEquals(middleToStart, middleToEnd, 1f);
|
||||||
|
});
|
||||||
|
|
||||||
|
AddAssert("Middle control point is not at start or end", () =>
|
||||||
|
Vector2.Distance(selectedSlider.Path.ControlPoints[^2].Position, oldStartPos) > 1 &&
|
||||||
|
Vector2.Distance(selectedSlider.Path.ControlPoints[^2].Position, oldEndPos) > 1
|
||||||
|
);
|
||||||
|
|
||||||
|
AddAssert("Slider has correct length", () =>
|
||||||
|
Precision.AlmostEquals(selectedSlider.Path.Distance, oldDistance));
|
||||||
|
|
||||||
|
AddAssert("Slider has correct start position", () =>
|
||||||
|
Vector2.Distance(selectedSlider.Position, oldEndPos) < 1);
|
||||||
|
|
||||||
|
AddAssert("Slider has correct end position", () =>
|
||||||
|
Vector2.Distance(selectedSlider.EndPosition, oldStartPos) < 1);
|
||||||
|
|
||||||
|
AddAssert("Control points have correct types", () =>
|
||||||
|
{
|
||||||
|
var newControlPointTypes = selectedSlider.Path.ControlPoints.Select(p => p.Type).ToArray();
|
||||||
|
|
||||||
|
return oldControlPointTypes.Take(newControlPointTypes.Length).SequenceEqual(newControlPointTypes);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestSegmentedSliderReversal()
|
||||||
|
{
|
||||||
|
PathControlPoint[] segmentedSliderPath =
|
||||||
|
[
|
||||||
|
new PathControlPoint
|
||||||
|
{
|
||||||
|
Position = new Vector2(0, 0),
|
||||||
|
Type = PathType.PERFECT_CURVE
|
||||||
|
},
|
||||||
|
new PathControlPoint
|
||||||
|
{
|
||||||
|
Position = new Vector2(100, 150),
|
||||||
|
},
|
||||||
|
new PathControlPoint
|
||||||
|
{
|
||||||
|
Position = new Vector2(75, -50),
|
||||||
|
Type = PathType.PERFECT_CURVE
|
||||||
|
},
|
||||||
|
new PathControlPoint
|
||||||
|
{
|
||||||
|
Position = new Vector2(225, -75),
|
||||||
|
},
|
||||||
|
new PathControlPoint
|
||||||
|
{
|
||||||
|
Position = new Vector2(350, 50),
|
||||||
|
Type = PathType.PERFECT_CURVE
|
||||||
|
},
|
||||||
|
new PathControlPoint
|
||||||
|
{
|
||||||
|
Position = new Vector2(500, -75),
|
||||||
|
},
|
||||||
|
new PathControlPoint
|
||||||
|
{
|
||||||
|
Position = new Vector2(350, -120),
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
Vector2 oldStartPos = default;
|
||||||
|
Vector2 oldEndPos = default;
|
||||||
|
double oldDistance = default;
|
||||||
|
|
||||||
|
var oldControlPointTypes = segmentedSliderPath.Select(p => p.Type);
|
||||||
|
|
||||||
|
AddStep("Add slider", () =>
|
||||||
|
{
|
||||||
|
var slider = new Slider
|
||||||
|
{
|
||||||
|
Position = new Vector2(0, 200),
|
||||||
|
Path = new SliderPath(segmentedSliderPath)
|
||||||
|
{
|
||||||
|
ExpectedDistance = { Value = 1314 }
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
EditorBeatmap.Add(slider);
|
||||||
|
|
||||||
|
oldStartPos = slider.Position;
|
||||||
|
oldEndPos = slider.EndPosition;
|
||||||
|
oldDistance = slider.Path.Distance;
|
||||||
|
});
|
||||||
|
|
||||||
|
AddStep("Select slider", () =>
|
||||||
|
{
|
||||||
|
var slider = (Slider)EditorBeatmap.HitObjects[0];
|
||||||
|
EditorBeatmap.SelectedHitObjects.Add(slider);
|
||||||
|
});
|
||||||
|
|
||||||
|
AddRepeatStep("Reverse slider", () =>
|
||||||
|
{
|
||||||
|
InputManager.PressKey(Key.LControl);
|
||||||
|
InputManager.Key(Key.G);
|
||||||
|
InputManager.ReleaseKey(Key.LControl);
|
||||||
|
}, 3);
|
||||||
|
|
||||||
|
AddAssert("First arc's control is not at the slider's middle", () =>
|
||||||
|
Vector2.Distance(selectedSlider.Path.ControlPoints[^2].Position, selectedSlider.Path.PositionAt(0.5)) > 1
|
||||||
|
);
|
||||||
|
|
||||||
|
AddAssert("Last arc's control is not at the slider's middle", () =>
|
||||||
|
Vector2.Distance(selectedSlider.Path.ControlPoints[1].Position, selectedSlider.Path.PositionAt(0.5)) > 1
|
||||||
|
);
|
||||||
|
|
||||||
|
AddAssert("First arc centered middle control point", () =>
|
||||||
|
{
|
||||||
|
var pathControlPoints = selectedSlider.Path.ControlPoints;
|
||||||
|
float middleToStart = Vector2.Distance(pathControlPoints[1].Position, pathControlPoints[0].Position);
|
||||||
|
float middleToEnd = Vector2.Distance(pathControlPoints[1].Position, pathControlPoints[2].Position);
|
||||||
|
|
||||||
|
return Precision.AlmostEquals(middleToStart, middleToEnd, 1f);
|
||||||
|
});
|
||||||
|
|
||||||
|
AddAssert("Last arc centered middle control point", () =>
|
||||||
|
{
|
||||||
|
var pathControlPoints = selectedSlider.Path.ControlPoints;
|
||||||
|
float middleToStart = Vector2.Distance(pathControlPoints[^2].Position, pathControlPoints[^3].Position);
|
||||||
|
float middleToEnd = Vector2.Distance(pathControlPoints[^2].Position, pathControlPoints[^1].Position);
|
||||||
|
|
||||||
|
return Precision.AlmostEquals(middleToStart, middleToEnd, 1f);
|
||||||
|
});
|
||||||
|
|
||||||
AddAssert("Slider has correct length", () =>
|
AddAssert("Slider has correct length", () =>
|
||||||
Precision.AlmostEquals(selectedSlider.Path.Distance, oldDistance));
|
Precision.AlmostEquals(selectedSlider.Path.Distance, oldDistance));
|
||||||
|
|
||||||
|
|||||||
88
osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModEasy.cs
Normal file
88
osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModEasy.cs
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
|
using System.Linq;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using osu.Game.Beatmaps;
|
||||||
|
using osu.Game.Rulesets.Mods;
|
||||||
|
using osu.Game.Rulesets.Osu.Mods;
|
||||||
|
using osu.Game.Tests.Beatmaps;
|
||||||
|
using osu.Game.Tests.Visual;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Osu.Tests.Mods
|
||||||
|
{
|
||||||
|
public partial class TestSceneOsuModEasy : OsuModTestScene
|
||||||
|
{
|
||||||
|
protected override bool AllowFail => true;
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestMultipleApplication()
|
||||||
|
{
|
||||||
|
bool reapplied = false;
|
||||||
|
CreateModTest(new ModTestData
|
||||||
|
{
|
||||||
|
Mods = [new OsuModEasy { Retries = { Value = 1 } }],
|
||||||
|
Autoplay = false,
|
||||||
|
CreateBeatmap = () =>
|
||||||
|
{
|
||||||
|
// do stuff to speed up fails
|
||||||
|
var b = new TestBeatmap(new OsuRuleset().RulesetInfo)
|
||||||
|
{
|
||||||
|
Difficulty = { DrainRate = 10 }
|
||||||
|
};
|
||||||
|
|
||||||
|
foreach (var ho in b.HitObjects)
|
||||||
|
ho.StartTime /= 4;
|
||||||
|
|
||||||
|
return b;
|
||||||
|
},
|
||||||
|
PassCondition = () =>
|
||||||
|
{
|
||||||
|
if (((ModEasyTestPlayer)Player).FailuresSuppressed > 0 && !reapplied)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
foreach (var mod in Player.GameplayState.Mods.OfType<IApplicableToDifficulty>())
|
||||||
|
mod.ApplyToDifficulty(new BeatmapDifficulty());
|
||||||
|
|
||||||
|
foreach (var mod in Player.GameplayState.Mods.OfType<IApplicableToPlayer>())
|
||||||
|
mod.ApplyToPlayer(Player);
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
// don't care if this fails. in fact a failure here is probably better than the alternative.
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
reapplied = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Player.GameplayState.HasFailed && ((ModEasyTestPlayer)Player).FailuresSuppressed <= 1;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override TestPlayer CreateModPlayer(Ruleset ruleset) => new ModEasyTestPlayer(CurrentTestData, AllowFail);
|
||||||
|
|
||||||
|
private partial class ModEasyTestPlayer : ModTestPlayer
|
||||||
|
{
|
||||||
|
public int FailuresSuppressed { get; private set; }
|
||||||
|
|
||||||
|
public ModEasyTestPlayer(ModTestData data, bool allowFail)
|
||||||
|
: base(data, allowFail)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override bool CheckModsAllowFailure()
|
||||||
|
{
|
||||||
|
bool failureAllowed = GameplayState.Mods.OfType<IApplicableFailOverride>().All(m => m.PerformFail());
|
||||||
|
|
||||||
|
if (!failureAllowed)
|
||||||
|
FailuresSuppressed++;
|
||||||
|
|
||||||
|
return failureAllowed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,7 +2,10 @@
|
|||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
|
using osu.Game.Rulesets.Osu.Beatmaps;
|
||||||
using osu.Game.Rulesets.Osu.Mods;
|
using osu.Game.Rulesets.Osu.Mods;
|
||||||
|
using osu.Game.Rulesets.Osu.Objects;
|
||||||
|
using osu.Game.Rulesets.Osu.UI;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Osu.Tests.Mods
|
namespace osu.Game.Rulesets.Osu.Tests.Mods
|
||||||
{
|
{
|
||||||
@@ -18,5 +21,39 @@ namespace osu.Game.Rulesets.Osu.Tests.Mods
|
|||||||
Autoplay = false,
|
Autoplay = false,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestSkipToFirstCircleNotSuppressed()
|
||||||
|
{
|
||||||
|
CreateModTest(new ModTestData
|
||||||
|
{
|
||||||
|
Mod = new OsuModFreezeFrame(),
|
||||||
|
CreateBeatmap = () => new OsuBeatmap
|
||||||
|
{
|
||||||
|
HitObjects =
|
||||||
|
{
|
||||||
|
new HitCircle { StartTime = 5000, Position = OsuPlayfield.BASE_SIZE / 2 }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
PassCondition = () => Player.GameplayClockContainer.GameplayStartTime > 0
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestSkipToFirstSpinnerNotSuppressed()
|
||||||
|
{
|
||||||
|
CreateModTest(new ModTestData
|
||||||
|
{
|
||||||
|
Mod = new OsuModFreezeFrame(),
|
||||||
|
CreateBeatmap = () => new OsuBeatmap
|
||||||
|
{
|
||||||
|
HitObjects =
|
||||||
|
{
|
||||||
|
new Spinner { StartTime = 5000, Position = OsuPlayfield.BASE_SIZE / 2 }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
PassCondition = () => Player.GameplayClockContainer.GameplayStartTime > 0
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,6 +27,9 @@ namespace osu.Game.Rulesets.Osu.Tests
|
|||||||
[TestCase("multi-segment-slider")]
|
[TestCase("multi-segment-slider")]
|
||||||
[TestCase("nan-slider")]
|
[TestCase("nan-slider")]
|
||||||
[TestCase("1124896")]
|
[TestCase("1124896")]
|
||||||
|
[TestCase("1341554")]
|
||||||
|
[TestCase("2593923")]
|
||||||
|
[TestCase("801165")]
|
||||||
public void Test(string name) => base.Test(name);
|
public void Test(string name) => base.Test(name);
|
||||||
|
|
||||||
protected override IEnumerable<ConvertValue> CreateConvertValue(HitObject hitObject)
|
protected override IEnumerable<ConvertValue> CreateConvertValue(HitObject hitObject)
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,941 @@
|
|||||||
|
osu file format v14
|
||||||
|
|
||||||
|
[General]
|
||||||
|
AudioLeadIn: 0
|
||||||
|
PreviewTime: 76429
|
||||||
|
Countdown: 0
|
||||||
|
SampleSet: Soft
|
||||||
|
StackLeniency: 0.2
|
||||||
|
Mode: 0
|
||||||
|
LetterboxInBreaks: 0
|
||||||
|
WidescreenStoryboard: 1
|
||||||
|
|
||||||
|
[Difficulty]
|
||||||
|
HPDrainRate:5
|
||||||
|
CircleSize:4.3
|
||||||
|
OverallDifficulty:8
|
||||||
|
ApproachRate:9.3
|
||||||
|
SliderMultiplier:2.99999995231628
|
||||||
|
SliderTickRate:1
|
||||||
|
|
||||||
|
[Events]
|
||||||
|
//Background and Video events
|
||||||
|
//Break Periods
|
||||||
|
//Storyboard Layer 0 (Background)
|
||||||
|
//Storyboard Layer 1 (Fail)
|
||||||
|
//Storyboard Layer 2 (Pass)
|
||||||
|
//Storyboard Layer 3 (Foreground)
|
||||||
|
//Storyboard Sound Samples
|
||||||
|
|
||||||
|
[TimingPoints]
|
||||||
|
763,444.444444444444,4,2,1,60,1,0
|
||||||
|
763,-111.111111111111,4,2,1,60,0,0
|
||||||
|
1929,-100,4,2,1,5,0,0
|
||||||
|
1985,-100,4,2,1,60,0,0
|
||||||
|
2040,-100,4,2,1,5,0,0
|
||||||
|
2096,-153.846153846153,4,2,1,60,0,0
|
||||||
|
2429,-133.333333333333,4,2,1,5,0,0
|
||||||
|
2540,-71.4285714285714,4,2,1,70,0,1
|
||||||
|
2985,-100,4,2,1,70,0,1
|
||||||
|
4485,-100,4,2,1,5,0,1
|
||||||
|
4540,-100,4,2,1,70,0,1
|
||||||
|
4707,-100,4,2,1,5,0,1
|
||||||
|
4762,-100,4,2,1,70,0,1
|
||||||
|
4929,-100,4,2,1,5,0,1
|
||||||
|
4985,-100,4,2,1,70,0,1
|
||||||
|
5096,-83.3333333333333,4,2,1,70,0,1
|
||||||
|
5429,-133.333333333333,4,2,1,70,0,1
|
||||||
|
5596,-133.333333333333,4,2,1,70,0,1
|
||||||
|
5652,-133.333333333333,4,2,1,70,0,1
|
||||||
|
5818,-133.333333333333,4,2,1,70,0,1
|
||||||
|
5874,-133.333333333333,4,2,1,70,0,1
|
||||||
|
6040,-133.333333333333,4,2,1,70,0,1
|
||||||
|
6096,-100,4,2,1,70,0,1
|
||||||
|
6540,-100,4,2,1,70,0,1
|
||||||
|
8040,-100,4,2,1,5,0,1
|
||||||
|
8096,-100,4,2,1,70,0,1
|
||||||
|
8262,-100,4,2,1,5,0,1
|
||||||
|
8318,-100,4,2,1,70,0,1
|
||||||
|
8485,-100,4,2,1,5,0,1
|
||||||
|
8540,-133.333333333333,4,2,1,70,0,1
|
||||||
|
8874,-100,4,2,1,5,0,1
|
||||||
|
8985,-100,4,2,1,70,0,1
|
||||||
|
9651,-100,4,2,1,70,0,1
|
||||||
|
10096,-100,4,2,1,70,0,1
|
||||||
|
11596,-100,4,2,1,5,0,1
|
||||||
|
11651,-100,4,2,1,70,0,1
|
||||||
|
11818,-100,4,2,1,5,0,1
|
||||||
|
11873,-100,4,2,1,70,0,1
|
||||||
|
11874,-80,4,2,1,70,0,1
|
||||||
|
12040,-80,4,2,1,5,0,1
|
||||||
|
12096,-80,4,2,1,70,0,1
|
||||||
|
12207,-133.333333333333,4,2,1,70,0,1
|
||||||
|
12429,-100,4,2,1,5,0,1
|
||||||
|
12540,-100,4,2,1,70,0,1
|
||||||
|
12707,-100,4,2,1,70,0,1
|
||||||
|
12763,-100,4,2,1,70,0,1
|
||||||
|
12929,-100,4,2,1,70,0,1
|
||||||
|
12985,-100,4,2,1,70,0,1
|
||||||
|
13429,-300,4,2,1,70,0,1
|
||||||
|
13651,-83.3333333333333,4,2,1,70,0,1
|
||||||
|
13874,-100,4,2,1,70,0,1
|
||||||
|
15151,-100,4,2,1,5,0,1
|
||||||
|
15207,-100,4,2,1,70,0,1
|
||||||
|
15373,-100,4,2,1,5,0,1
|
||||||
|
15429,-100,4,2,1,70,0,1
|
||||||
|
15596,-100,4,2,1,5,0,1
|
||||||
|
15651,-100,4,2,1,70,0,1
|
||||||
|
15985,-100,4,2,1,5,0,1
|
||||||
|
16096,-100,4,2,1,70,0,1
|
||||||
|
16262,-100,4,2,1,70,0,1
|
||||||
|
16318,-83.3333333333333,4,2,1,70,0,1
|
||||||
|
16651,-100,4,2,1,70,0,1
|
||||||
|
16762,-133.333333333333,4,2,1,60,0,0
|
||||||
|
17096,-133.333333333333,4,2,1,5,0,0
|
||||||
|
17207,-200,4,2,1,60,0,0
|
||||||
|
18096,-66.6666666666667,4,2,1,60,0,0
|
||||||
|
18262,-66.6666666666667,4,2,1,5,0,0
|
||||||
|
18318,-66.6666666666667,4,2,1,60,0,0
|
||||||
|
18540,-100,4,2,1,60,0,0
|
||||||
|
18874,-100,4,2,1,5,0,0
|
||||||
|
18985,-100,4,2,1,60,0,0
|
||||||
|
19985,-100,4,2,1,60,0,0
|
||||||
|
20485,-100,4,2,1,5,0,0
|
||||||
|
20540,-100,4,2,1,60,0,0
|
||||||
|
20707,-100,4,2,1,5,0,0
|
||||||
|
20762,-200,4,2,1,60,0,0
|
||||||
|
20985,-100,4,2,1,60,0,0
|
||||||
|
21095,-100,4,2,1,60,0,0
|
||||||
|
21374,-100,4,2,1,5,0,0
|
||||||
|
21429,-100,4,2,1,60,0,0
|
||||||
|
21596,-100,4,2,1,5,0,0
|
||||||
|
21651,-100,4,2,1,60,0,0
|
||||||
|
21818,-100,4,2,1,5,0,0
|
||||||
|
21874,-66.6666666666667,4,2,1,60,0,0
|
||||||
|
21985,-100,4,2,1,60,0,0
|
||||||
|
22096,-100,4,2,1,60,0,0
|
||||||
|
22985,-200,4,2,1,60,0,0
|
||||||
|
23318,-100,4,2,1,60,0,0
|
||||||
|
23429,-100,4,2,1,60,0,0
|
||||||
|
23540,-100,4,2,1,60,0,0
|
||||||
|
23651,-100,4,2,1,60,0,0
|
||||||
|
23762,-100,4,2,1,60,0,0
|
||||||
|
23874,-133.333333333333,4,2,1,60,0,0
|
||||||
|
24208,-133.333333333333,4,2,1,5,0,0
|
||||||
|
24318,-200,4,2,1,5,0,0
|
||||||
|
24319,-200,4,2,1,60,0,0
|
||||||
|
24540,-100,4,2,1,60,0,0
|
||||||
|
24651,-66.6666666666667,4,2,1,60,0,0
|
||||||
|
24874,-100,4,2,1,60,0,0
|
||||||
|
25374,-100,4,2,1,5,0,0
|
||||||
|
25429,-100,4,2,1,60,0,0
|
||||||
|
27096,-100,4,2,1,60,0,0
|
||||||
|
27596,-100,4,2,1,5,0,0
|
||||||
|
27651,-100,4,2,1,60,0,0
|
||||||
|
27818,-100,4,2,1,5,0,0
|
||||||
|
27873,-133.333333333333,4,2,1,60,0,0
|
||||||
|
28096,-100,4,2,1,60,0,0
|
||||||
|
28206,-100,4,2,1,60,0,0
|
||||||
|
28485,-100,4,2,1,5,0,0
|
||||||
|
28540,-100,4,2,1,60,0,0
|
||||||
|
28707,-100,4,2,1,5,0,0
|
||||||
|
28762,-100,4,2,1,60,0,0
|
||||||
|
28929,-100,4,2,1,5,0,0
|
||||||
|
28985,-66.6666666666667,4,2,1,60,0,0
|
||||||
|
29151,-100,4,2,1,60,0,0
|
||||||
|
29207,-100,4,2,1,60,0,0
|
||||||
|
29651,-100,4,2,1,60,0,0
|
||||||
|
30429,-100,4,2,1,60,0,0
|
||||||
|
30540,-58.8235294117647,4,2,1,60,0,0
|
||||||
|
30874,-58.8235294117647,4,2,1,5,0,0
|
||||||
|
30985,-58.8235294117647,4,2,1,60,0,0
|
||||||
|
31040,-100,4,2,1,5,0,0
|
||||||
|
31429,-100,4,2,1,60,0,0
|
||||||
|
32485,-100,4,2,1,60,0,0
|
||||||
|
32540,-100,4,2,1,60,0,0
|
||||||
|
32707,-100,4,2,1,60,0,0
|
||||||
|
32762,-100,4,2,1,60,0,0
|
||||||
|
32985,-100,4,2,1,60,0,0
|
||||||
|
34318,-50,4,2,1,60,0,0
|
||||||
|
34485,-100,4,2,1,5,0,0
|
||||||
|
34540,-100,4,2,1,60,0,0
|
||||||
|
35151,-100,4,2,1,5,0,0
|
||||||
|
35207,-100,4,2,1,60,0,0
|
||||||
|
35374,-100,4,2,1,5,0,0
|
||||||
|
35430,-100,4,2,1,60,0,0
|
||||||
|
35818,-100,4,2,1,5,0,0
|
||||||
|
35874,-200,4,2,1,60,0,0
|
||||||
|
36429,-100,4,2,1,60,0,0
|
||||||
|
37818,-100,4,2,1,5,0,0
|
||||||
|
37874,-100,4,2,1,60,0,0
|
||||||
|
38040,-100,4,2,1,5,0,0
|
||||||
|
38096,-50,4,2,1,60,0,0
|
||||||
|
38151,-100,4,2,1,5,0,0
|
||||||
|
38540,-100,4,2,1,60,0,0
|
||||||
|
39596,-100,4,2,1,5,0,0
|
||||||
|
39651,-100,4,2,1,60,0,0
|
||||||
|
39818,-100,4,2,1,60,0,0
|
||||||
|
39873,-100,4,2,1,60,0,0
|
||||||
|
40096,-100,4,2,1,60,0,0
|
||||||
|
41429,-50,4,2,1,60,0,0
|
||||||
|
41596,-100,4,2,1,5,0,0
|
||||||
|
41651,-100,4,2,1,60,0,0
|
||||||
|
41818,-100,4,2,1,5,0,0
|
||||||
|
41874,-100,4,2,1,60,0,0
|
||||||
|
42040,-100,4,2,1,5,0,0
|
||||||
|
42096,-100,4,2,1,60,0,0
|
||||||
|
44318,-100,4,2,1,60,0,0
|
||||||
|
44762,-83.3333333333333,4,2,1,60,0,0
|
||||||
|
45207,-66.6666666666667,4,2,1,45,0,0
|
||||||
|
45651,-133.333333333333,4,2,1,45,0,0
|
||||||
|
51540,-133.333333333333,4,2,1,50,0,0
|
||||||
|
51651,-133.333333333333,4,2,1,45,0,0
|
||||||
|
52318,-133.333333333333,4,2,1,45,0,0
|
||||||
|
58540,-76.9230769230769,4,2,1,45,0,0
|
||||||
|
58818,-100,4,2,1,45,0,0
|
||||||
|
58874,-111.111111111111,4,2,1,45,0,0
|
||||||
|
59318,-111.111111111111,4,2,1,45,0,0
|
||||||
|
59429,-83.3333333333333,4,2,1,60,0,0
|
||||||
|
59540,-83.3333333333333,4,2,1,5,0,0
|
||||||
|
59874,-100,4,2,1,60,0,0
|
||||||
|
60096,-100,4,2,1,5,0,0
|
||||||
|
60207,-100,4,2,1,60,0,0
|
||||||
|
60707,-100,4,2,1,5,0,0
|
||||||
|
60763,-100,4,2,1,60,0,0
|
||||||
|
60818,-100,4,2,1,5,0,0
|
||||||
|
60874,-100,4,2,1,60,0,0
|
||||||
|
60929,-100,4,2,1,5,0,0
|
||||||
|
60985,-100,4,2,1,60,0,0
|
||||||
|
61040,-100,4,2,1,5,0,0
|
||||||
|
61096,-100,4,2,1,60,0,0
|
||||||
|
61151,-100,4,2,1,5,0,0
|
||||||
|
61207,-100,4,2,1,60,0,0
|
||||||
|
61596,-100,4,2,1,5,0,0
|
||||||
|
61651,-100,4,2,1,60,0,0
|
||||||
|
61762,-83.3333333333333,4,2,1,60,0,0
|
||||||
|
61985,-100,4,2,1,5,0,0
|
||||||
|
62096,-100,4,2,1,60,0,0
|
||||||
|
62151,-100,4,2,1,5,0,0
|
||||||
|
62207,-100,4,2,1,60,0,0
|
||||||
|
62262,-100,4,2,1,5,0,0
|
||||||
|
62318,-100,4,2,1,60,0,0
|
||||||
|
62374,-100,4,2,1,5,0,0
|
||||||
|
62430,-100,4,2,1,60,0,0
|
||||||
|
62485,-100,4,2,1,5,0,0
|
||||||
|
62540,-100,4,2,1,60,0,0
|
||||||
|
62596,-100,4,2,1,5,0,0
|
||||||
|
62651,-100,4,2,1,60,0,0
|
||||||
|
62707,-100,4,2,1,5,0,0
|
||||||
|
62762,-100,4,2,1,60,0,0
|
||||||
|
62818,-100,4,2,1,5,0,0
|
||||||
|
62874,-100,4,2,1,60,0,0
|
||||||
|
62929,-100,4,2,1,60,0,0
|
||||||
|
62930,-100,4,2,1,5,0,0
|
||||||
|
62985,-100,4,2,1,60,0,0
|
||||||
|
63707,-100,4,2,1,5,0,0
|
||||||
|
63762,-100,4,2,1,60,0,0
|
||||||
|
64262,-100,4,2,1,5,0,0
|
||||||
|
64318,-100,4,2,1,60,0,0
|
||||||
|
64485,-100,4,2,1,5,0,0
|
||||||
|
64540,-100,4,2,1,60,0,0
|
||||||
|
64596,-100,4,2,1,5,0,0
|
||||||
|
64651,-100,4,2,1,60,0,0
|
||||||
|
64707,-100,4,2,1,5,0,0
|
||||||
|
64762,-71.4285714285714,4,2,1,60,0,0
|
||||||
|
64929,-71.4285714285714,4,2,1,5,0,0
|
||||||
|
64984,-133.333333333333,4,2,1,60,0,0
|
||||||
|
65151,-133.333333333333,4,2,1,5,0,0
|
||||||
|
65206,-71.4285714285714,4,2,1,60,0,0
|
||||||
|
65374,-71.4285714285714,4,2,1,5,0,0
|
||||||
|
65429,-133.333333333333,4,2,1,60,0,0
|
||||||
|
65596,-133.333333333333,4,2,1,5,0,0
|
||||||
|
65651,-100,4,2,1,60,0,0
|
||||||
|
66540,-66.6666666666667,4,2,1,60,0,0
|
||||||
|
66596,-66.6666666666667,4,2,1,5,0,0
|
||||||
|
66929,-100,4,2,1,5,0,0
|
||||||
|
66985,-200,4,2,1,60,0,0
|
||||||
|
67207,-200,4,2,1,5,0,0
|
||||||
|
67318,-100,4,2,1,60,0,0
|
||||||
|
67818,-100,4,2,1,5,0,0
|
||||||
|
67874,-100,4,2,1,60,0,0
|
||||||
|
67929,-100,4,2,1,5,0,0
|
||||||
|
67985,-100,4,2,1,60,0,0
|
||||||
|
68040,-100,4,2,1,5,0,0
|
||||||
|
68096,-100,4,2,1,60,0,0
|
||||||
|
68151,-100,4,2,1,5,0,0
|
||||||
|
68207,-100,4,2,1,60,0,0
|
||||||
|
68262,-100,4,2,1,5,0,0
|
||||||
|
68318,-100,4,2,1,60,0,0
|
||||||
|
68874,-83.3333333333333,4,2,1,60,0,0
|
||||||
|
69096,-100,4,2,1,60,0,0
|
||||||
|
69097,-100,4,2,1,5,0,0
|
||||||
|
69207,-100,4,2,1,60,0,0
|
||||||
|
69263,-100,4,2,1,5,0,0
|
||||||
|
69319,-100,4,2,1,60,0,0
|
||||||
|
69374,-100,4,2,1,5,0,0
|
||||||
|
69430,-100,4,2,1,60,0,0
|
||||||
|
69486,-100,4,2,1,5,0,0
|
||||||
|
69542,-100,4,2,1,60,0,0
|
||||||
|
69597,-100,4,2,1,5,0,0
|
||||||
|
69651,-100,4,2,1,60,0,0
|
||||||
|
69707,-100,4,2,1,5,0,0
|
||||||
|
69762,-100,4,2,1,60,0,0
|
||||||
|
69818,-100,4,2,1,5,0,0
|
||||||
|
69874,-100,4,2,1,60,0,0
|
||||||
|
69929,-100,4,2,1,5,0,0
|
||||||
|
69985,-100,4,2,1,60,0,0
|
||||||
|
70040,-100,4,2,1,60,0,0
|
||||||
|
70041,-100,4,2,1,5,0,0
|
||||||
|
70096,-100,4,2,1,60,0,0
|
||||||
|
70818,-100,4,2,1,5,0,0
|
||||||
|
70873,-100,4,2,1,60,0,0
|
||||||
|
71207,-71.4285714285714,4,2,1,60,0,0
|
||||||
|
71429,-100,4,2,1,60,0,0
|
||||||
|
71874,-71.4285714285714,4,2,1,60,0,0
|
||||||
|
72041,-71.4285714285714,4,2,1,5,0,0
|
||||||
|
72096,-133.333333333333,4,2,1,60,0,0
|
||||||
|
72263,-133.333333333333,4,2,1,5,0,0
|
||||||
|
72318,-71.4285714285714,4,2,1,60,0,0
|
||||||
|
72485,-71.4285714285714,4,2,1,5,0,0
|
||||||
|
72540,-133.333333333333,4,2,1,60,0,0
|
||||||
|
72985,-66.6666666666667,4,2,1,60,0,0
|
||||||
|
73207,-100,4,2,1,60,0,0
|
||||||
|
73651,-133.333333333333,4,2,1,45,0,0
|
||||||
|
75318,-133.333333333333,4,2,1,5,0,0
|
||||||
|
75429,-133.333333333333,4,2,1,45,0,0
|
||||||
|
76762,-100,4,2,1,45,0,0
|
||||||
|
77096,-100,4,2,1,5,0,0
|
||||||
|
77207,-100,4,2,1,70,0,1
|
||||||
|
77818,-100,4,2,1,5,0,1
|
||||||
|
77874,-100,4,2,1,70,0,1
|
||||||
|
78262,-100,4,2,1,5,0,1
|
||||||
|
78318,-100,4,2,1,70,0,1
|
||||||
|
78540,-83.3333333333333,4,2,1,70,0,1
|
||||||
|
78985,-100,4,2,1,70,0,1
|
||||||
|
79596,-100,4,2,1,5,0,1
|
||||||
|
79651,-100,4,2,1,70,0,1
|
||||||
|
80040,-100,4,2,1,5,0,1
|
||||||
|
80096,-100,4,2,1,70,0,1
|
||||||
|
80318,-83.3333333333333,4,2,1,70,0,1
|
||||||
|
84318,-100,4,2,1,70,0,1
|
||||||
|
84929,-100,4,2,1,5,0,1
|
||||||
|
84985,-100,4,2,1,70,0,1
|
||||||
|
85207,-100,4,2,1,70,0,1
|
||||||
|
85374,-100,4,2,1,5,0,1
|
||||||
|
85429,-100,4,2,1,70,0,1
|
||||||
|
85651,-83.3333333333333,4,2,1,70,0,1
|
||||||
|
86096,-100,4,2,1,70,0,1
|
||||||
|
86707,-100,4,2,1,5,0,1
|
||||||
|
86762,-100,4,2,1,70,0,1
|
||||||
|
88818,-100,4,2,1,5,0,1
|
||||||
|
88874,-100,4,2,1,70,0,1
|
||||||
|
88929,-100,4,2,1,5,0,1
|
||||||
|
88985,-100,4,2,1,70,0,1
|
||||||
|
89040,-100,4,2,1,5,0,1
|
||||||
|
89096,-100,4,2,1,70,0,1
|
||||||
|
92040,-100,4,2,1,5,0,1
|
||||||
|
92096,-100,4,2,1,70,0,1
|
||||||
|
92485,-100,4,2,1,5,0,1
|
||||||
|
92540,-100,4,2,1,70,0,1
|
||||||
|
97651,-200,4,2,1,70,0,1
|
||||||
|
97818,-200,4,2,1,5,0,1
|
||||||
|
97874,-66.6666666666667,4,2,1,70,0,1
|
||||||
|
97985,-66.6666666666667,4,2,1,70,0,1
|
||||||
|
98040,-66.6666666666667,4,2,1,5,0,1
|
||||||
|
98096,-133.333333333333,4,2,1,70,0,1
|
||||||
|
98262,-133.333333333333,4,2,1,5,0,1
|
||||||
|
98318,-66.6666666666667,4,2,1,70,0,1
|
||||||
|
98540,-100,4,2,1,70,0,1
|
||||||
|
99151,-100,4,2,1,5,0,1
|
||||||
|
99207,-100,4,2,1,70,0,1
|
||||||
|
99596,-100,4,2,1,5,0,1
|
||||||
|
99651,-100,4,2,1,70,0,1
|
||||||
|
103040,-100,4,2,1,5,0,1
|
||||||
|
103096,-100,4,2,1,70,0,1
|
||||||
|
103151,-100,4,2,1,5,0,1
|
||||||
|
103207,-100,4,2,1,70,0,1
|
||||||
|
103262,-100,4,2,1,5,0,1
|
||||||
|
103318,-100,4,2,1,70,0,1
|
||||||
|
105207,-83.3333333333333,4,2,1,70,0,1
|
||||||
|
105540,-83.3333333333333,4,2,1,70,0,1
|
||||||
|
105651,-133.333333333333,4,2,1,60,0,0
|
||||||
|
105985,-133.333333333333,4,2,1,5,0,0
|
||||||
|
106096,-200,4,2,1,60,0,0
|
||||||
|
106985,-66.6666666666667,4,2,1,60,0,0
|
||||||
|
107151,-66.6666666666667,4,2,1,5,0,0
|
||||||
|
107207,-66.6666666666667,4,2,1,60,0,0
|
||||||
|
107429,-100,4,2,1,60,0,0
|
||||||
|
107763,-100,4,2,1,5,0,0
|
||||||
|
107874,-100,4,2,1,60,0,0
|
||||||
|
108874,-100,4,2,1,60,0,0
|
||||||
|
109374,-100,4,2,1,5,0,0
|
||||||
|
109429,-100,4,2,1,60,0,0
|
||||||
|
109596,-100,4,2,1,5,0,0
|
||||||
|
109651,-200,4,2,1,60,0,0
|
||||||
|
109929,-100,4,2,1,60,0,0
|
||||||
|
109984,-100,4,2,1,60,0,0
|
||||||
|
110262,-100,4,2,1,5,0,0
|
||||||
|
110318,-100,4,2,1,60,0,0
|
||||||
|
110485,-100,4,2,1,5,0,0
|
||||||
|
110540,-100,4,2,1,60,0,0
|
||||||
|
110707,-100,4,2,1,5,0,0
|
||||||
|
110762,-66.6666666666667,4,2,1,60,0,0
|
||||||
|
110929,-100,4,2,1,60,0,0
|
||||||
|
110985,-133.333333333333,4,2,1,60,0,0
|
||||||
|
111429,-133.333333333333,4,2,1,60,0,0
|
||||||
|
111596,-133.333333333333,4,2,1,60,0,0
|
||||||
|
111651,-133.333333333333,4,2,1,60,0,0
|
||||||
|
111818,-133.333333333333,4,2,1,60,0,0
|
||||||
|
111874,-100,4,2,1,60,0,1
|
||||||
|
112318,-83.3333333333333,4,2,1,60,0,1
|
||||||
|
112429,-100,4,2,1,5,0,0
|
||||||
|
|
||||||
|
|
||||||
|
[Colours]
|
||||||
|
Combo1 : 112,75,180
|
||||||
|
Combo2 : 0,255,255
|
||||||
|
Combo3 : 255,15,117
|
||||||
|
Combo4 : 255,135,15
|
||||||
|
|
||||||
|
[HitObjects]
|
||||||
|
309,230,763,37,0,3:0:0:0:
|
||||||
|
485,146,985,2,0,L|406:167,1,67.4999968671799,8|0,3:0|0:0,0:0:0:0:
|
||||||
|
374,249,1207,2,0,L|299:227,1,67.4999968671799,8|0,3:0|0:0,0:0:0:0:
|
||||||
|
196,91,1429,2,0,L|191:44,3,33.7499984335899,0|0|0|0,3:0|3:0|3:0|3:0,0:0:0:0:
|
||||||
|
124,173,1651,2,0,L|131:222,2,44.9999979114532,0|0|0,3:0|3:0|3:0,0:0:0:0:
|
||||||
|
221,284,1874,2,0,L|213:208,1,67.4999968671799,0|0,3:0|3:0,0:0:0:0:
|
||||||
|
292,86,2096,38,0,L|310:234,1,146.249990980625,12|0,3:0|0:0,0:0:0:0:
|
||||||
|
314,328,2540,38,0,B|280:359|280:359|230:320|252:242|313:230,1,209.999990253448,0|0,3:0|0:0,0:0:0:0:
|
||||||
|
421,300,2874,1,0,0:0:0:0:
|
||||||
|
421,300,2985,2,0,P|461:288|491:253,1,74.999998807907,8|0,3:0|0:0,0:0:0:0:
|
||||||
|
309,231,3207,2,0,P|297:190|305:153,1,74.999998807907,4|0,0:0|0:0,0:0:0:0:
|
||||||
|
394,22,3429,5,0,3:0:0:0:
|
||||||
|
461,72,3540,2,0,B|477:103|477:103|461:148,1,74.999998807907,0|4,0:0|0:0,0:0:0:0:
|
||||||
|
378,183,3762,2,0,L|206:157,1,149.999997615814,0|0,0:0|0:0,0:0:0:0:
|
||||||
|
229,161,4096,2,0,P|227:202|211:250,1,74.999998807907,4|0,0:0|0:0,0:0:0:0:
|
||||||
|
61,384,4318,38,0,P|101:359|134:322,1,74.999998807907,0|0,3:0|0:0,0:0:0:0:
|
||||||
|
317,310,4540,2,0,P|267:305|226:288,1,74.999998807907,4|0,0:0|0:0,0:0:0:0:
|
||||||
|
141,110,4762,2,0,B|121:175|152:226|152:226|152:202|161:183,1,149.999997615814,8|4,3:0|0:0,0:0:0:0:
|
||||||
|
155,196,5096,6,0,P|67:211|79:286,1,179.999991645813,0|0,0:0|0:0,0:0:0:0:
|
||||||
|
212,366,5429,38,0,P|207:335|174:281,1,56.2500012516975,4|0,0:0|0:0,0:0:0:0:
|
||||||
|
206,286,5651,2,0,P|236:297|299:295,1,56.2500012516975,8|0,3:0|0:0,0:0:0:0:
|
||||||
|
281,321,5874,2,0,P|257:340|227:396,1,56.2500012516975,4|0,0:0|0:0,0:0:0:0:
|
||||||
|
124,246,6096,6,0,P|198:198|277:232,1,149.999997615814,0|0,3:0|0:0,0:0:0:0:
|
||||||
|
253,211,6429,1,0,0:0:0:0:
|
||||||
|
276,99,6540,2,0,P|335:139|369:215,1,149.999997615814,8|4,3:0|0:0,0:0:0:0:
|
||||||
|
368,208,6874,1,0,0:0:0:0:
|
||||||
|
430,96,6985,37,0,3:0:0:0:
|
||||||
|
497,147,7096,2,0,P|507:189|488:244,1,74.999998807907,0|4,0:0|0:0,0:0:0:0:
|
||||||
|
414,379,7318,2,0,B|383:322|421:267|421:267|421:308,1,149.999997615814,0|0,0:0|0:0,0:0:0:0:
|
||||||
|
421,298,7651,2,0,P|378:312|336:304,1,74.999998807907,4|0,0:0|0:0,0:0:0:0:
|
||||||
|
270,170,7874,6,0,P|275:228|236:278,1,74.999998807907,0|0,3:0|0:0,0:0:0:0:
|
||||||
|
94,300,8096,2,0,P|133:263|208:274,1,74.999998807907,4|0,0:0|0:0,0:0:0:0:
|
||||||
|
261,374,8318,2,0,L|176:365,1,74.999998807907,8|0,3:0|0:0,0:0:0:0:
|
||||||
|
38,377,8540,2,0,L|55:197,1,168.750003755093,4|0,0:0|0:0,0:0:0:0:
|
||||||
|
123,25,8985,38,0,L|132:110,1,74.999998807907,4|0,0:0|0:0,0:0:0:0:
|
||||||
|
217,242,9207,2,0,L|237:168,1,74.999998807907,8|0,3:0|0:0,0:0:0:0:
|
||||||
|
48,92,9429,5,4,0:0:0:0:
|
||||||
|
63,176,9540,1,0,0:0:0:0:
|
||||||
|
83,259,9651,38,0,P|167:223|231:255,1,149.999997615814,0|0,3:0|0:0,0:0:0:0:
|
||||||
|
274,312,9985,1,0,0:0:0:0:
|
||||||
|
274,312,10096,2,0,L|354:292,1,74.999998807907,8|0,3:0|0:0,0:0:0:0:
|
||||||
|
459,225,10318,2,0,L|375:204,1,74.999998807907,4|0,0:0|0:0,0:0:0:0:
|
||||||
|
269,107,10540,1,0,3:0:0:0:
|
||||||
|
276,54,10651,1,0,0:0:0:0:
|
||||||
|
313,17,10762,1,4,0:0:0:0:
|
||||||
|
363,9,10874,1,0,0:0:0:0:
|
||||||
|
363,9,11096,5,0,0:0:0:0:
|
||||||
|
432,68,11207,2,0,P|444:107|425:154,1,74.999998807907,4|0,0:0|0:0,0:0:0:0:
|
||||||
|
309,252,11429,38,0,P|297:195|321:158,1,74.999998807907,0|0,3:0|0:0,0:0:0:0:
|
||||||
|
450,316,11651,2,0,L|361:312,1,74.999998807907,4|0,0:0|0:0,0:0:0:0:
|
||||||
|
160,341,11874,2,0,B|187:380|187:380|233:309|177:235,1,187.499997019767,8|4,3:0|0:0,0:0:0:0:
|
||||||
|
116,200,12207,6,0,P|52:224|122:264,1,168.750003755093,0|4,0:0|0:0,0:0:0:0:
|
||||||
|
297,91,12762,37,8,3:0:0:0:
|
||||||
|
276,44,12874,1,0,0:0:0:0:
|
||||||
|
226,27,12985,1,4,0:0:0:0:
|
||||||
|
187,63,13096,1,0,0:0:0:0:
|
||||||
|
196,115,13207,1,0,0:0:0:0:
|
||||||
|
376,144,13429,2,0,L|378:121,2,16.6666664017571,0|0|0,0:0|0:0|0:0,0:0:0:0:
|
||||||
|
436,220,13651,6,0,B|395:211|373:164|373:164|332:208|264:185,1,179.999991645813,8|4,3:0|0:0,0:0:0:0:
|
||||||
|
276,44,13985,1,0,0:0:0:0:
|
||||||
|
196,115,14096,38,0,L|139:124,4,37.4999994039535,0|0|0|0|4,3:0|0:0|0:0|0:0|0:0,0:0:0:0:
|
||||||
|
82,69,14429,1,0,0:0:0:0:
|
||||||
|
106,190,14540,2,0,L|126:276,1,74.999998807907,8|0,3:0|0:0,0:0:0:0:
|
||||||
|
218,383,14762,2,0,L|234:309,1,74.999998807907,4|0,0:0|0:0,0:0:0:0:
|
||||||
|
26,231,14985,5,0,3:0:0:0:
|
||||||
|
253,202,15207,37,0,0:0:0:0:
|
||||||
|
331,271,15318,1,0,0:0:0:0:
|
||||||
|
233,309,15429,1,8,3:0:0:0:
|
||||||
|
389,73,15651,6,0,P|410:22|447:112,1,224.999996423721,4|0,3:0|0:0,0:0:0:0:
|
||||||
|
391,165,16096,1,0,0:0:0:0:
|
||||||
|
377,177,16207,1,0,0:0:0:0:
|
||||||
|
365,187,16318,38,0,B|253:261|221:119|94:192,1,269.999987468719,0|0,0:0|0:0,0:0:0:0:
|
||||||
|
73,319,16762,22,0,P|133:336|116:236,1,168.750003755093,4|0,3:0|0:0,0:0:0:0:
|
||||||
|
139,258,17207,6,0,P|138:315|69:283,1,112.500002503395,8|0,3:0|0:0,0:0:0:0:
|
||||||
|
92,323,17762,37,0,0:0:0:0:
|
||||||
|
43,245,17874,1,4,0:0:0:0:
|
||||||
|
4,322,17985,1,0,0:0:0:0:
|
||||||
|
133,245,18096,1,0,3:0:0:0:
|
||||||
|
29,105,18318,6,0,L|38:40,3,56.2500012516975,4|0|0|0,3:0|0:0|0:0|0:0,0:0:0:0:
|
||||||
|
50,30,18540,38,0,P|111:56|193:25,1,149.999997615814,0|0,3:0|0:0,0:0:0:0:
|
||||||
|
240,120,18985,2,0,P|328:91|394:125,1,149.999997615814,8|4,3:0|0:0,0:0:0:0:
|
||||||
|
409,213,19318,2,0,B|377:226|377:226|243:200,1,149.999997615814,0|0,0:0|0:0,0:0:0:0:
|
||||||
|
119,187,19651,2,0,L|127:286,1,74.999998807907,4|0,0:0|0:0,0:0:0:0:
|
||||||
|
179,338,19874,1,8,3:0:0:0:
|
||||||
|
45,307,19985,6,0,L|3:297,2,37.4999994039535,0|0|4,0:0|0:0|0:0,0:0:0:0:
|
||||||
|
103,380,20207,1,0,3:0:0:0:
|
||||||
|
212,257,20318,38,0,P|233:218|231:171,1,74.999998807907,0|0,3:0|0:0,0:0:0:0:
|
||||||
|
111,118,20540,1,4,0:0:0:0:
|
||||||
|
111,118,20762,6,0,L|197:109,1,74.999998807907,8|4,3:0|0:0,0:0:0:0:
|
||||||
|
256,18,21096,37,0,0:0:0:0:
|
||||||
|
337,121,21207,2,0,P|350:60|403:16,1,112.49999821186,0|0,3:0|0:0,0:0:0:0:
|
||||||
|
384,26,21429,2,0,P|406:86|465:122,1,112.49999821186,0|0,0:0|0:0,0:0:0:0:
|
||||||
|
443,114,21651,2,0,P|377:105|327:131,1,112.49999821186,8|0,3:0|0:0,0:0:0:0:
|
||||||
|
352,223,21874,6,0,B|369:230|369:230|391:228|391:228|416:239|416:239|440:235|440:235|462:244|462:244|489:249,1,112.500002503395,4|0,0:0|0:0,0:0:0:0:
|
||||||
|
322,343,22096,37,0,3:0:0:0:
|
||||||
|
259,270,22207,2,0,P|223:276|182:263,2,74.999998807907,0|4|0,0:0|0:0|0:0,0:0:0:0:
|
||||||
|
86,360,22540,5,8,3:0:0:0:
|
||||||
|
15,295,22651,2,0,L|0:201,2,74.999998807907,0|4|0,0:0|0:0|0:0,0:0:0:0:
|
||||||
|
94,384,22985,38,0,P|118:328|112:277,1,112.49999821186,0|0,3:0|0:0,0:0:0:0:
|
||||||
|
0,211,23429,22,0,L|76:196,1,74.999998807907,12|0,3:0|0:0,0:0:0:0:
|
||||||
|
215,134,23651,2,0,L|114:110,1,74.999998807907,12|0,3:0|0:0,0:0:0:0:
|
||||||
|
33,124,23874,22,0,L|43:2,1,112.49999821186,0|0,3:0|0:0,0:0:0:0:
|
||||||
|
150,269,24318,2,0,L|162:194,1,74.999998807907,0|4,3:0|0:0,0:0:0:0:
|
||||||
|
229,134,24651,6,0,L|386:164,1,112.500002503395,12|0,3:0|0:0,0:0:0:0:
|
||||||
|
486,268,24874,37,0,0:0:0:0:
|
||||||
|
410,119,24985,1,4,0:0:0:0:
|
||||||
|
381,213,25096,1,0,0:0:0:0:
|
||||||
|
512,120,25207,1,0,3:0:0:0:
|
||||||
|
247,36,25429,6,0,L|191:25,3,37.4999994039535,4|0|0|0,3:0|0:0|0:0|0:0,0:0:0:0:
|
||||||
|
185,24,25651,2,0,B|145:72|145:72|174:164,1,149.999997615814,0|0,3:0|0:0,0:0:0:0:
|
||||||
|
253,219,26096,2,0,B|281:311|281:311|228:382,1,149.999997615814,8|4,3:0|0:0,0:0:0:0:
|
||||||
|
100,363,26429,38,0,L|259:354,1,149.999997615814,0|0,0:0|0:0,0:0:0:0:
|
||||||
|
404,262,26762,1,4,0:0:0:0:
|
||||||
|
390,352,26874,1,0,0:0:0:0:
|
||||||
|
314,295,26985,1,8,3:0:0:0:
|
||||||
|
425,256,27096,6,0,L|492:246,2,37.4999994039535,0|0|4,0:0|0:0|0:0,0:0:0:0:
|
||||||
|
329,216,27318,1,0,3:0:0:0:
|
||||||
|
193,177,27429,38,0,L|266:161,1,74.999998807907,0|0,3:0|0:0,0:0:0:0:
|
||||||
|
322,107,27651,1,4,0:0:0:0:
|
||||||
|
322,107,27874,2,0,L|310:238,1,112.500002503395,8|4,3:0|0:0,0:0:0:0:
|
||||||
|
110,299,28207,5,0,0:0:0:0:
|
||||||
|
164,231,28318,2,0,B|168:303|168:303|121:338,1,112.49999821186,0|0,3:0|0:0,0:0:0:0:
|
||||||
|
30,284,28540,2,0,B|90:244|90:244|144:267,1,112.49999821186,0|0,0:0|0:0,0:0:0:0:
|
||||||
|
148,371,28762,2,0,B|83:338|83:338|76:280,1,112.49999821186,8|0,3:0|0:0,0:0:0:0:
|
||||||
|
194,201,28985,38,0,B|207:210|207:210|227:210|227:210|243:217|243:217|265:218|265:218|282:227|282:227|305:225|305:225|325:238,1,112.500002503395,4|0,0:0|0:0,0:0:0:0:
|
||||||
|
492,114,29207,6,0,P|445:136|410:138,1,74.999998807907,0|0,3:0|0:0,0:0:0:0:
|
||||||
|
324,102,29429,2,0,P|291:68|280:29,1,74.999998807907,4|0,0:0|0:0,0:0:0:0:
|
||||||
|
418,17,29651,1,8,3:0:0:0:
|
||||||
|
495,201,29874,1,4,3:2:0:0:
|
||||||
|
221,136,30096,37,0,3:0:0:0:
|
||||||
|
299,188,30207,2,0,B|316:251|316:251|271:352,1,149.999997615814,4|0,3:0|0:0,0:0:0:0:
|
||||||
|
115,334,30540,6,0,P|11:252|167:266,1,382.500001215934,0|0,0:0|0:0,0:0:0:0:
|
||||||
|
216,326,30985,38,0,L|304:331,1,63.7500002026557,4|0,3:0|0:0,0:0:0:0:
|
||||||
|
280,330,31429,6,0,L|293:241,1,74.999998807907,8|0,3:0|0:0,0:0:0:0:
|
||||||
|
426,252,31651,2,0,L|439:163,1,74.999998807907,0|0,0:0|0:0,0:0:0:0:
|
||||||
|
253,158,31874,37,0,3:0:0:0:
|
||||||
|
258,132,31985,1,0,0:0:0:0:
|
||||||
|
337,111,32096,5,4,0:0:0:0:
|
||||||
|
341,85,32207,1,0,0:0:0:0:
|
||||||
|
271,30,32318,38,0,B|212:42|212:42|141:19,1,112.49999821186,8|0,3:0|0:0,0:0:0:0:
|
||||||
|
163,26,32540,2,0,L|144:181,1,149.999997615814,4|0,0:0|3:0,0:0:0:0:
|
||||||
|
445,343,32985,22,0,B|439:234|439:234|384:269,1,149.999997615814,4|8,0:0|3:0,0:0:0:0:
|
||||||
|
240,257,33429,2,0,B|263:148|263:148|291:205,1,149.999997615814,4|0,0:0|3:0,0:0:0:0:
|
||||||
|
68,333,33874,2,0,B|83:233|83:233|41:256,1,149.999997615814,4|8,0:0|3:0,0:0:0:0:
|
||||||
|
344,347,34318,22,0,B|368:372|368:372|455:355|455:355|472:308,1,149.999997615814,4|0,0:0|0:0,0:0:0:0:
|
||||||
|
452,255,34540,2,0,B|389:212|389:212|332:273,1,149.999997615814,0|4,3:0|0:0,0:0:0:0:
|
||||||
|
256,220,34874,5,0,0:0:0:0:
|
||||||
|
256,220,34985,2,0,B|256:128,1,74.999998807907,8|0,3:0|0:0,0:0:0:0:
|
||||||
|
256,70,35207,2,0,B|256:162,1,74.999998807907,4|0,0:0|0:0,0:0:0:0:
|
||||||
|
112,312,35429,37,0,3:0:0:0:
|
||||||
|
60,255,35540,2,0,B|123:212|123:212|180:273,1,149.999997615814,0|0,0:0|0:0,0:0:0:0:
|
||||||
|
169,350,35874,6,0,B|144:375|144:375|57:358|57:358|40:311,1,149.999997615814,8|0,3:0|3:0,0:0:0:0:
|
||||||
|
62,169,36429,6,0,L|76:267,2,74.999998807907,0|4|0,0:0|0:0|0:0,0:0:0:0:
|
||||||
|
134,61,36762,1,8,3:0:0:0:
|
||||||
|
201,113,36874,2,0,L|215:211,2,74.999998807907,0|4|0,0:0|0:0|0:0,0:0:0:0:
|
||||||
|
298,272,37207,6,0,L|315:184,1,74.999998807907,0|0,3:0|0:0,0:0:0:0:
|
||||||
|
330,114,37429,1,4,0:0:0:0:
|
||||||
|
446,176,37540,2,0,B|404:214|404:214|307:197,1,149.999997615814,4|0,3:0|0:0,0:0:0:0:
|
||||||
|
231,240,37874,2,0,P|223:199|231:162,1,74.999998807907,4|0,3:0|0:0,0:0:0:0:
|
||||||
|
325,285,38096,6,0,L|154:300,1,149.999997615814,4|0,3:0|0:0,0:0:0:0:
|
||||||
|
175,298,38540,6,0,L|163:396,1,74.999998807907,8|0,3:0|0:0,0:0:0:0:
|
||||||
|
75,208,38762,2,0,L|63:306,1,74.999998807907,0|0,0:0|0:0,0:0:0:0:
|
||||||
|
233,74,38985,37,0,3:0:0:0:
|
||||||
|
231,98,39096,1,0,0:0:0:0:
|
||||||
|
156,139,39207,5,4,0:0:0:0:
|
||||||
|
155,165,39318,1,0,0:0:0:0:
|
||||||
|
227,215,39429,38,0,P|282:209|352:230,1,112.49999821186,8|0,3:0|0:0,0:0:0:0:
|
||||||
|
336,222,39651,2,0,L|366:67,1,149.999997615814,4|0,0:0|3:0,0:0:0:0:
|
||||||
|
81,35,40096,22,0,B|82:105|82:105|118:136|118:136|132:89,1,149.999997615814,4|8,0:0|3:0,0:0:0:0:
|
||||||
|
272,158,40540,2,0,B|270:228|270:228|234:259|234:259|220:212,1,149.999997615814,4|0,0:0|3:0,0:0:0:0:
|
||||||
|
423,36,40985,2,0,B|400:102|400:102|423:143|423:143|453:104,1,149.999997615814,4|8,0:0|3:0,0:0:0:0:
|
||||||
|
512,278,41429,6,0,P|415:258|361:293,1,149.999997615814,4|0,0:0|0:0,0:0:0:0:
|
||||||
|
359,302,41651,6,0,B|320:264|320:264|310:187,1,112.49999821186,0|0,3:0|0:0,0:0:0:0:
|
||||||
|
322,190,41874,2,0,L|449:171,1,112.49999821186,4|0,0:0|0:0,0:0:0:0:
|
||||||
|
443,159,42096,1,8,3:0:0:0:
|
||||||
|
240,52,42318,6,0,B|255:79|255:79|241:135,1,74.999998807907,4|0,0:0|0:0,0:0:0:0:
|
||||||
|
177,166,42540,1,0,3:0:0:0:
|
||||||
|
163,151,42651,2,0,B|161:207|161:207|192:240|192:240|189:299,1,149.999997615814,0|0,0:0|0:0,0:0:0:0:
|
||||||
|
131,365,42985,2,0,P|198:322|280:345,1,149.999997615814,8|4,3:0|0:0,0:0:0:0:
|
||||||
|
335,377,43318,1,0,0:0:0:0:
|
||||||
|
442,239,43429,38,0,B|456:178|456:178|422:136|422:136|427:68|427:68|449:112,1,224.999996423721,0|0,3:0|0:0,0:0:0:0:
|
||||||
|
444,103,43874,2,0,P|402:118|356:120,1,74.999998807907,0|0,0:0|0:0,0:0:0:0:
|
||||||
|
249,28,44096,2,0,P|295:35|324:48,1,74.999998807907,0|0,0:0|0:0,0:0:0:0:
|
||||||
|
364,201,44318,5,0,0:0:0:0:
|
||||||
|
332,195,44429,1,0,0:0:0:0:
|
||||||
|
251,135,44540,37,0,0:0:0:0:
|
||||||
|
281,123,44651,1,0,0:0:0:0:
|
||||||
|
332,195,44762,6,0,B|356:269|324:333|324:333|303:293,1,179.999991645813,4|0,0:3|0:0,0:0:0:0:
|
||||||
|
61,25,45207,38,0,L|88:158,1,112.500002503395,0|0,3:0|0:0,0:0:0:0:
|
||||||
|
84,136,45651,1,8,3:0:0:0:
|
||||||
|
84,136,46096,1,0,3:0:0:0:
|
||||||
|
176,33,46207,2,0,L|164:103,1,56.2500012516975,0|0,0:0|0:0,0:0:0:0:
|
||||||
|
219,207,46429,2,0,L|232:152,1,56.2500012516975,0|8,0:0|3:0,0:0:0:0:
|
||||||
|
312,65,46651,1,0,0:0:0:0:
|
||||||
|
312,65,46762,2,0,L|398:94,1,56.2500012516975,0|0,0:0|0:0,0:0:0:0:
|
||||||
|
512,176,46985,5,0,3:0:0:0:
|
||||||
|
421,192,47096,1,0,0:0:0:0:
|
||||||
|
421,192,47429,1,8,3:0:0:0:
|
||||||
|
402,357,47651,37,0,0:0:0:0:
|
||||||
|
394,277,47762,1,0,0:0:0:0:
|
||||||
|
328,324,47874,1,0,3:0:0:0:
|
||||||
|
328,324,48318,1,8,3:0:0:0:
|
||||||
|
110,357,48540,5,0,0:0:0:0:
|
||||||
|
118,277,48651,1,0,0:0:0:0:
|
||||||
|
184,324,48763,1,0,3:0:0:0:
|
||||||
|
110,357,48874,1,0,0:0:0:0:
|
||||||
|
110,357,49207,1,8,3:0:0:0:
|
||||||
|
110,357,49651,1,0,3:0:0:0:
|
||||||
|
0,283,49762,38,0,P|41:301|97:295,1,56.2500012516975,0|0,0:0|0:0,0:0:0:0:
|
||||||
|
188,219,49985,2,0,P|168:236|137:246,1,56.2500012516975,0|8,0:0|3:0,0:0:0:0:
|
||||||
|
49,137,50207,1,0,0:0:0:0:
|
||||||
|
49,137,50318,2,0,P|65:184|93:205,1,56.2500012516975,0|0,0:0|0:0,0:0:0:0:
|
||||||
|
107,67,50540,5,0,3:0:0:0:
|
||||||
|
32,15,50651,1,0,0:0:0:0:
|
||||||
|
32,15,50985,1,8,3:0:0:0:
|
||||||
|
265,114,51207,37,0,0:0:0:0:
|
||||||
|
254,196,51318,1,0,0:0:0:0:
|
||||||
|
241,279,51429,1,0,3:0:0:0:
|
||||||
|
241,279,51651,1,0,0:0:0:0:
|
||||||
|
336,207,51762,6,0,P|397:191|371:274,1,168.750003755093,0|0,0:0|0:0,0:0:0:0:
|
||||||
|
83,206,52318,5,0,3:0:0:0:
|
||||||
|
83,206,52429,2,0,L|101:260,1,56.2500012516975,0|0,0:0|0:0,0:0:0:0:
|
||||||
|
40,383,52651,2,0,P|70:355|90:324,1,56.2500012516975,0|8,0:0|3:0,0:0:0:0:
|
||||||
|
214,334,52874,1,0,0:0:0:0:
|
||||||
|
214,334,52985,2,0,P|171:322|140:304,1,56.2500012516975,0|0,0:0|0:0,0:0:0:0:
|
||||||
|
151,160,53207,5,0,3:0:0:0:
|
||||||
|
188,135,53318,1,0,0:0:0:0:
|
||||||
|
232,129,53429,1,0,0:0:0:0:
|
||||||
|
273,146,53540,1,0,0:0:0:0:
|
||||||
|
339,198,53651,37,8,3:0:0:0:
|
||||||
|
383,199,53762,1,0,0:0:0:0:
|
||||||
|
426,185,53874,1,0,0:0:0:0:
|
||||||
|
450,147,53985,1,0,0:0:0:0:
|
||||||
|
444,61,54096,6,0,P|414:28|377:15,1,56.2500012516975,0|0,3:0|0:0,0:0:0:0:
|
||||||
|
301,28,54318,2,0,P|268:48|255:77,1,56.2500012516975,0|0,0:0|0:0,0:0:0:0:
|
||||||
|
189,271,54540,38,0,P|209:222|204:198,1,56.2500012516975,8|0,3:0|0:0,0:0:0:0:
|
||||||
|
186,114,54762,2,0,P|152:74|124:68,1,56.2500012516975,0|0,0:0|0:0,0:0:0:0:
|
||||||
|
27,137,54985,5,0,3:0:0:0:
|
||||||
|
34,167,55096,1,0,0:0:0:0:
|
||||||
|
122,204,55207,37,0,0:0:0:0:
|
||||||
|
116,178,55318,1,0,0:0:0:0:
|
||||||
|
48,249,55429,5,8,3:0:0:0:
|
||||||
|
54,274,55540,1,0,0:0:0:0:
|
||||||
|
124,329,55651,38,0,P|157:326|200:310,1,56.2500012516975,0|0,0:0|0:0,0:0:0:0:
|
||||||
|
320,185,55874,5,0,3:0:0:0:
|
||||||
|
287,175,55985,1,0,0:0:0:0:
|
||||||
|
254,181,56096,2,0,P|258:221|264:241,1,56.2500012516975,0|0,0:0|0:0,0:0:0:0:
|
||||||
|
337,347,56318,2,0,P|348:321|350:293,1,56.2500012516975,8|0,3:0|0:0,0:0:0:0:
|
||||||
|
418,197,56540,37,0,0:0:0:0:
|
||||||
|
418,197,56651,2,0,L|492:180,1,56.2500012516975,0|0,0:0|3:0,0:0:0:0:
|
||||||
|
329,114,56874,2,0,L|262:94,1,56.2500012516975,0|0,0:0|0:0,0:0:0:0:
|
||||||
|
436,59,57096,6,0,L|413:126,1,56.2500012516975,0|8,0:0|3:0,0:0:0:0:
|
||||||
|
332,194,57318,2,0,L|353:259,2,56.2500012516975,0|0|0,0:0|0:0|0:0,0:0:0:0:
|
||||||
|
202,194,57651,37,0,3:0:0:0:
|
||||||
|
224,233,57762,1,0,0:0:0:0:
|
||||||
|
222,279,57874,1,0,0:0:0:0:
|
||||||
|
193,314,57985,1,0,0:0:0:0:
|
||||||
|
144,244,58096,5,0,0:0:0:0:
|
||||||
|
127,214,58207,1,0,0:0:0:0:
|
||||||
|
126,180,58318,1,0,0:0:0:0:
|
||||||
|
139,149,58429,1,0,0:0:0:0:
|
||||||
|
224,113,58540,38,0,B|262:88|235:70|189:83|189:83|224:138|194:193,1,194.999987974167
|
||||||
|
299,319,58874,1,0,0:0:0:0:
|
||||||
|
299,319,58985,2,0,B|316:283|314:237|314:237|278:226|278:226|320:243|359:227,1,202.49999060154,4|0,0:0|0:0,0:0:0:0:
|
||||||
|
428,181,59429,22,0,P|454:129|399:4,1,179.999991645813,0|0,3:0|0:0,0:0:0:0:
|
||||||
|
418,18,59874,2,0,L|373:15,6,24.9999996026357,8|0|0|0|0|0|4,3:0|0:0|0:0|0:0|0:0|0:0|0:0,0:0:0:0:
|
||||||
|
428,181,60207,5,0,0:0:0:0:
|
||||||
|
352,209,60318,1,0,3:0:0:0:
|
||||||
|
278,177,60429,1,0,0:0:0:0:
|
||||||
|
208,225,60540,2,0,L|222:267,2,37.4999994039535,4|0|0,0:0|0:0|0:0,0:0:0:0:
|
||||||
|
71,144,60762,38,0,L|65:109,3,24.9999996026357,8|0|0|0,3:0|0:0|0:0|0:0,0:0:0:0:
|
||||||
|
145,86,60985,1,4,0:0:0:0:
|
||||||
|
163,127,61096,1,0,0:0:0:0:
|
||||||
|
161,171,61207,1,0,3:0:0:0:
|
||||||
|
136,208,61318,1,0,0:0:0:0:
|
||||||
|
99,231,61429,2,0,B|91:279|91:279|117:314,1,74.999998807907,4|0,0:0|0:0,0:0:0:0:
|
||||||
|
177,378,61651,5,8,3:0:0:0:
|
||||||
|
177,378,61762,2,0,B|231:371|231:371|272:326|272:326|345:319,1,179.999991645813
|
||||||
|
417,293,62096,1,0,3:0:0:0:
|
||||||
|
438,263,62207,1,0,0:0:0:0:
|
||||||
|
436,225,62318,1,4,0:0:0:0:
|
||||||
|
412,196,62429,1,0,0:0:0:0:
|
||||||
|
320,172,62540,6,0,P|307:192|291:204,1,37.4999994039535,8|0,3:0|0:0,0:0:0:0:
|
||||||
|
291,147,62651,2,0,P|274:156|245:153,1,37.4999994039535,0|0,0:0|0:0,0:0:0:0:
|
||||||
|
276,114,62762,2,0,P|250:107|234:94,1,37.4999994039535,4|0,0:0|0:0,0:0:0:0:
|
||||||
|
283,81,62874,2,0,P|265:61|260:45,1,37.4999994039535,0|0,0:0|0:0,0:0:0:0:
|
||||||
|
365,31,62985,38,0,P|398:44|442:49,1,74.999998807907,0|0,3:0|0:0,0:0:0:0:
|
||||||
|
512,169,63207,2,0,P|466:163|421:176,1,74.999998807907,4|0,0:0|0:0,0:0:0:0:
|
||||||
|
350,107,63429,1,8,3:0:0:0:
|
||||||
|
293,237,63540,38,0,L|276:158,1,74.999998807907,0|0,0:0|0:0,0:0:0:0:
|
||||||
|
428,269,63762,2,0,B|373:275|373:275|338:249|338:249|267:255,1,149.999997615814,0|0,0:0|0:0,0:0:0:0:
|
||||||
|
191,318,64096,2,0,B|182:355|182:355|212:395,1,74.999998807907,4|0,0:0|0:0,0:0:0:0:
|
||||||
|
192,186,64318,5,8,3:0:0:0:
|
||||||
|
135,253,64429,2,0,L|56:270,2,74.999998807907,0|4|0,0:0|0:0|0:0,0:0:0:0:
|
||||||
|
24,136,64762,38,0,P|69:76|158:75,1,157.499992690086,0|0,3:0|0:0,0:0:0:0:
|
||||||
|
160,80,64985,6,0,P|193:102|255:102,1,84.3750018775463,4|0,0:0|0:0,0:0:0:0:
|
||||||
|
276,34,65207,38,0,L|290:212,1,157.499992690086,8|0,3:0|0:0,0:0:0:0:
|
||||||
|
291,219,65429,6,0,L|311:132,1,84.3750018775463,4|0,0:0|0:0,0:0:0:0:
|
||||||
|
381,111,65651,38,0,B|418:126|418:126|460:126,1,74.999998807907,0|0,3:0|0:0,0:0:0:0:
|
||||||
|
221,163,65874,2,0,B|186:143|186:143|139:153,1,74.999998807907,4|0,0:0|0:0,0:0:0:0:
|
||||||
|
41,231,66096,1,8,3:0:0:0:
|
||||||
|
49,267,66207,1,0,0:0:0:0:
|
||||||
|
56,303,66318,1,4,0:0:0:0:
|
||||||
|
67,288,66429,1,4,0:0:0:0:
|
||||||
|
77,270,66540,6,0,P|171:255|72:350,1,337.500007510185,0|0,0:0|0:0,0:0:0:0:
|
||||||
|
95,356,66985,38,0,L|185:343,1,74.999998807907,8|4,3:0|0:0,0:0:0:0:
|
||||||
|
274,286,67318,6,0,B|289:324|289:324|268:378,1,74.999998807907,0|0,0:0|3:0,0:0:0:0:
|
||||||
|
191,227,67540,1,0,0:0:0:0:
|
||||||
|
255,168,67651,2,0,L|264:116,2,37.4999994039535,4|0|0,0:0|0:0|0:0,0:0:0:0:
|
||||||
|
147,83,67874,2,0,L|154:108,3,24.9999996026357,8|0|0|0,3:0|0:0|0:0|0:0,0:0:0:0:
|
||||||
|
80,148,68096,38,0,L|98:224,1,74.999998807907,4|0,0:0|0:0,0:0:0:0:
|
||||||
|
125,356,68318,1,0,3:0:0:0:
|
||||||
|
0,319,68429,1,0,0:0:0:0:
|
||||||
|
0,319,68540,2,0,L|76:294,1,74.999998807907,4|0,0:0|0:0,0:0:0:0:
|
||||||
|
277,219,68762,5,8,3:0:0:0:
|
||||||
|
277,219,68874,2,0,B|327:199|327:199|293:138|197:173,1,179.999991645813,0|0,0:0|0:0,0:0:0:0:
|
||||||
|
157,273,69207,37,0,3:0:0:0:
|
||||||
|
175,316,69318,1,0,0:0:0:0:
|
||||||
|
212,334,69429,1,4,0:0:0:0:
|
||||||
|
254,333,69540,1,0,0:0:0:0:
|
||||||
|
332,268,69651,38,0,P|333:237|343:213,1,37.4999994039535,8|0,3:0|0:0,0:0:0:0:
|
||||||
|
373,265,69762,2,0,P|386:239|404:232,1,37.4999994039535,0|0,0:0|0:0,0:0:0:0:
|
||||||
|
413,284,69874,2,0,P|430:269|454:269,1,37.4999994039535,4|0,0:0|0:0,0:0:0:0:
|
||||||
|
433,318,69985,2,0,P|452:320|474:337,1,37.4999994039535,4|0,0:0|0:0,0:0:0:0:
|
||||||
|
401,384,70096,6,0,P|353:378|319:346,1,74.999998807907,0|0,3:0|0:0,0:0:0:0:
|
||||||
|
251,251,70318,2,0,P|240:196|260:154,1,74.999998807907,4|0,0:0|0:0,0:0:0:0:
|
||||||
|
401,18,70540,1,8,3:0:0:0:
|
||||||
|
401,18,70651,2,0,P|409:54|398:90,1,74.999998807907,0|0,0:0|0:0,0:0:0:0:
|
||||||
|
327,193,70874,2,0,L|304:45,1,149.999997615814,0|0,0:0|0:0,0:0:0:0:
|
||||||
|
290,26,71207,6,0,L|308:144,1,104.999995126724,0|0,0:0|0:0,0:0:0:0:
|
||||||
|
272,302,71429,2,0,L|187:288,1,74.999998807907,8|0,3:0|0:0,0:0:0:0:
|
||||||
|
33,217,71651,37,4,0:0:0:0:
|
||||||
|
27,187,71762,1,4,0:0:0:0:
|
||||||
|
20,157,71874,2,0,B|103:140|103:140|162:58,1,157.499992690086,0|0,3:0|0:0,0:0:0:0:
|
||||||
|
145,82,72096,6,0,L|218:75,1,56.2500012516975,0|0,0:0|0:0,0:0:0:0:
|
||||||
|
336,136,72318,38,0,P|331:213|231:208,1,157.499992690086
|
||||||
|
263,232,72540,6,0,L|278:300,1,56.2500012516975,0|0,0:0|0:0,0:0:0:0:
|
||||||
|
183,384,72762,2,0,L|172:307,1,56.2500012516975,0|0,0:0|0:0,0:0:0:0:
|
||||||
|
37,140,72985,38,0,B|10:168|10:168|17:204|17:204|54:220|54:220|89:196|89:196|87:157|87:157|57:138,1,225.00000500679
|
||||||
|
275,372,73651,6,0,P|320:352|387:369,1,112.500002503395
|
||||||
|
380,364,74096,2,0,L|436:358,1,56.2500012516975,0|0,0:0|0:0,0:0:0:0:
|
||||||
|
495,271,74318,2,0,L|424:282,1,56.2500012516975,0|0,0:0|0:0,0:0:0:0:
|
||||||
|
339,270,74540,1,0,0:0:0:0:
|
||||||
|
339,270,74651,1,0,0:0:0:0:
|
||||||
|
339,270,74762,2,0,L|329:196,1,56.2500012516975,0|0,0:0|0:0,0:0:0:0:
|
||||||
|
408,46,74985,38,0,L|392:120,1,56.2500012516975
|
||||||
|
220,230,75207,2,0,L|209:156,1,56.2500012516975,0|0,0:0|0:0,0:0:0:0:
|
||||||
|
282,7,75429,37,0,0:0:0:0:
|
||||||
|
300,98,75540,1,0,0:0:0:0:
|
||||||
|
197,25,75651,5,0,0:0:0:0:
|
||||||
|
222,103,75762,1,0,0:0:0:0:
|
||||||
|
126,69,75874,5,0,0:0:0:0:
|
||||||
|
153,134,75985,1,0,0:0:0:0:
|
||||||
|
76,145,76096,5,0,0:0:0:0:
|
||||||
|
116,179,76207,1,0,0:0:0:0:
|
||||||
|
70,222,76318,5,0,0:0:0:0:
|
||||||
|
111,222,76429,1,0,0:0:0:0:
|
||||||
|
134,253,76540,6,0,P|135:298|126:314,1,56.2500012516975,0|0,0:0|0:0,0:0:0:0:
|
||||||
|
21,384,76762,2,0,P|124:354|260:391,1,224.999996423721,0|0,0:0|0:0,0:0:0:0:
|
||||||
|
384,366,77207,22,0,L|394:268,1,74.999998807907,0|0,3:0|0:0,0:0:0:0:
|
||||||
|
499,62,77429,2,0,L|486:135,1,74.999998807907,4|0,0:0|0:0,0:0:0:0:
|
||||||
|
507,237,77651,2,0,P|450:231|388:184,1,112.49999821186,8|0,3:0|0:0,0:0:0:0:
|
||||||
|
404,203,77874,2,0,L|313:217,1,74.999998807907,4|0,0:0|0:0,0:0:0:0:
|
||||||
|
113,212,78096,6,0,P|128:267|111:328,1,112.49999821186,0|0,3:0|0:0,0:0:0:0:
|
||||||
|
115,319,78318,2,0,L|213:340,1,74.999998807907,4|0,0:0|0:0,0:0:0:0:
|
||||||
|
274,371,78540,38,0,L|257:186,1,179.999991645813,8|0,3:0|0:0,0:0:0:0:
|
||||||
|
128,139,78874,1,0,0:0:0:0:
|
||||||
|
128,139,78985,6,0,L|230:128,1,74.999998807907,0|0,3:0|0:0,0:0:0:0:
|
||||||
|
365,34,79207,37,4,0:0:0:0:
|
||||||
|
430,114,79318,1,0,0:0:0:0:
|
||||||
|
361,184,79429,2,0,P|304:170|277:110,1,112.49999821186,8|0,3:0|0:0,0:0:0:0:
|
||||||
|
278,126,79651,2,0,L|189:133,1,74.999998807907,4|0,0:0|0:0,0:0:0:0:
|
||||||
|
64,263,79874,6,0,B|37:230|37:230|50:143,1,112.49999821186,0|0,3:0|0:0,0:0:0:0:
|
||||||
|
66,119,80096,2,0,L|80:210,1,74.999998807907,4|0,0:0|0:0,0:0:0:0:
|
||||||
|
71,361,80318,38,0,B|135:350|135:350|182:305|182:305|243:297,1,179.999991645813,8|0,3:0|0:0,0:0:0:0:
|
||||||
|
302,247,80651,1,0,0:0:0:0:
|
||||||
|
222,211,80762,1,0,3:0:0:0:
|
||||||
|
478,344,80985,5,4,0:0:0:0:
|
||||||
|
491,309,81096,5,0,0:0:0:0:
|
||||||
|
498,265,81207,5,8,3:0:0:0:
|
||||||
|
485,223,81318,5,0,0:0:0:0:
|
||||||
|
458,179,81429,5,4,0:0:0:0:
|
||||||
|
418,147,81540,5,0,0:0:0:0:
|
||||||
|
352,126,81651,5,0,3:0:0:0:
|
||||||
|
281,149,81762,5,0,0:0:0:0:
|
||||||
|
239,221,81874,5,4,0:0:0:0:
|
||||||
|
159,262,81985,5,0,0:0:0:0:
|
||||||
|
66,234,82096,5,8,3:0:0:0:
|
||||||
|
11,145,82207,5,0,0:0:0:0:
|
||||||
|
55,33,82318,5,4,0:0:0:0:
|
||||||
|
273,44,82540,37,0,3:0:0:0:
|
||||||
|
320,103,82651,1,0,0:0:0:0:
|
||||||
|
394,118,82762,1,4,0:0:0:0:
|
||||||
|
468,100,82874,1,0,0:0:0:0:
|
||||||
|
507,36,82985,1,8,3:0:0:0:
|
||||||
|
495,19,83207,5,4,0:0:0:0:
|
||||||
|
335,83,83318,1,0,0:0:0:0:
|
||||||
|
453,81,83429,1,0,3:0:0:0:
|
||||||
|
283,24,83540,2,0,P|196:37|141:120,1,149.999997615814,0|0,0:0|0:0,0:0:0:0:
|
||||||
|
60,238,83874,1,8,3:0:0:0:
|
||||||
|
21,164,83985,2,0,P|59:149|175:193,1,149.999997615814,0|8,0:0|3:0,0:0:0:0:
|
||||||
|
252,206,84318,38,0,P|271:160|264:125,1,74.999998807907,0|0,3:0|0:0,0:0:0:0:
|
||||||
|
139,257,84540,2,0,P|131:302|149:340,1,74.999998807907,4|0,0:0|0:0,0:0:0:0:
|
||||||
|
240,379,84762,2,0,B|330:360|330:360|298:344,1,112.49999821186,8|0,3:0|0:0,0:0:0:0:
|
||||||
|
312,351,84985,2,0,P|279:321|270:287,1,74.999998807907,4|0,0:0|0:0,0:0:0:0:
|
||||||
|
359,165,85207,6,0,B|389:202|389:202|368:282,1,112.49999821186,0|0,3:0|0:0,0:0:0:0:
|
||||||
|
373,265,85429,2,0,L|454:282,1,74.999998807907,4|0,0:0|0:0,0:0:0:0:
|
||||||
|
498,139,85651,38,0,P|446:120|396:0,1,179.999991645813,8|0,3:0|0:0,0:0:0:0:
|
||||||
|
394,13,85985,1,0,0:0:0:0:
|
||||||
|
301,92,86096,6,0,L|214:83,1,74.999998807907,0|0,3:0|0:0,0:0:0:0:
|
||||||
|
66,66,86318,1,4,0:0:0:0:
|
||||||
|
13,136,86429,1,0,0:0:0:0:
|
||||||
|
72,193,86540,2,0,P|120:210|190:178,1,112.49999821186,8|0,3:0|0:0,0:0:0:0:
|
||||||
|
176,192,86762,2,0,P|154:237|160:288,1,74.999998807907,4|0,0:0|0:0,0:0:0:0:
|
||||||
|
309,370,86985,37,0,3:0:0:0:
|
||||||
|
359,310,87096,1,0,0:0:0:0:
|
||||||
|
283,297,87207,2,0,L|203:318,1,74.999998807907,4|0,0:0|0:0,0:0:0:0:
|
||||||
|
4,203,87429,2,0,B|55:211|55:211|82:255|82:255|134:266,1,149.999997615814,8|0,3:0|0:0,0:0:0:0:
|
||||||
|
238,217,87762,1,0,0:0:0:0:
|
||||||
|
183,120,87874,6,0,L|89:111,1,74.999998807907,0|0,3:0|0:0,0:0:0:0:
|
||||||
|
98,33,88096,2,0,L|23:26,1,74.999998807907,4|0,0:0|0:0,0:0:0:0:
|
||||||
|
306,182,88318,38,0,L|400:173,1,74.999998807907,8|0,3:0|0:0,0:0:0:0:
|
||||||
|
391,95,88540,2,0,L|465:88,1,74.999998807907,4|0,0:0|0:0,0:0:0:0:
|
||||||
|
232,28,88762,2,0,L|220:92,1,37.4999994039535,0|0,3:0|0:0,0:0:0:0:
|
||||||
|
243,39,88874,2,0,L|231:103,1,37.4999994039535,0|0,0:0|0:0,0:0:0:0:
|
||||||
|
256,50,88985,2,0,L|251:87,1,37.4999994039535,4|0,0:0|0:0,0:0:0:0:
|
||||||
|
485,87,89207,6,0,L|493:51,3,37.4999994039535,8|0|0|0,3:0|0:0|0:0|0:0,0:0:0:0:
|
||||||
|
396,120,89429,2,0,L|411:197,1,74.999998807907,4|0,0:0|0:0,0:0:0:0:
|
||||||
|
471,317,89651,38,0,P|411:299|320:336,1,149.999997615814,0|4,3:0|0:0,0:0:0:0:
|
||||||
|
61,239,90096,2,0,P|121:221|212:258,1,149.999997615814,8|4,3:0|0:0,0:0:0:0:
|
||||||
|
367,21,90540,6,0,P|336:57|328:104,1,74.999998807907,0|0,3:0|0:0,0:0:0:0:
|
||||||
|
163,96,90762,2,0,P|194:132|202:179,1,74.999998807907,0|0,0:0|0:0,0:0:0:0:
|
||||||
|
190,346,90985,37,8,3:0:0:0:
|
||||||
|
328,272,91096,1,0,0:0:0:0:
|
||||||
|
154,272,91207,5,8,3:0:0:0:
|
||||||
|
365,338,91318,1,0,0:0:0:0:
|
||||||
|
257,382,91429,38,0,B|290:333|224:286|269:219,1,149.999997615814,4|4,3:0|0:0,0:0:0:0:
|
||||||
|
325,196,91762,1,0,0:0:0:0:
|
||||||
|
325,196,91874,2,0,P|365:210|436:184,1,112.49999821186,8|0,3:0|0:0,0:0:0:0:
|
||||||
|
430,190,92096,2,0,B|418:110,1,74.999998807907,4|0,0:0|0:0,0:0:0:0:
|
||||||
|
313,19,92318,2,0,L|190:36,1,112.49999821186,0|0,3:0|0:0,0:0:0:0:
|
||||||
|
201,34,92540,2,0,B|214:117,1,74.999998807907,4|0,0:0|0:0,0:0:0:0:
|
||||||
|
209,252,92762,5,8,3:0:0:0:
|
||||||
|
156,261,92874,1,0,0:0:0:0:
|
||||||
|
112,231,92985,1,4,0:0:0:0:
|
||||||
|
60,222,93096,1,0,0:0:0:0:
|
||||||
|
13,247,93207,38,0,P|4:288|19:328,1,74.999998807907,0|0,3:0|0:0,0:0:0:0:
|
||||||
|
173,186,93429,1,4,0:0:0:0:
|
||||||
|
215,120,93540,1,0,0:0:0:0:
|
||||||
|
162,49,93651,2,0,P|125:39|76:61,1,74.999998807907,8|0,3:0|0:0,0:0:0:0:
|
||||||
|
234,138,93874,2,0,P|273:157|313:148,1,74.999998807907,4|0,0:0|0:0,0:0:0:0:
|
||||||
|
385,39,94096,5,0,3:0:0:0:
|
||||||
|
337,286,94318,2,0,L|322:373,1,74.999998807907,4|0,0:0|0:0,0:0:0:0:
|
||||||
|
409,327,94540,2,0,P|418:277|280:230,1,224.999996423721,8|0,3:0|0:0,0:0:0:0:
|
||||||
|
239,319,94985,2,0,P|218:357|173:373,1,74.999998807907,0|0,3:0|0:0,0:0:0:0:
|
||||||
|
34,344,95207,37,4,0:0:0:0:
|
||||||
|
21,309,95318,5,0,0:0:0:0:
|
||||||
|
14,265,95429,5,8,3:0:0:0:
|
||||||
|
27,223,95540,5,0,0:0:0:0:
|
||||||
|
54,179,95651,5,4,0:0:0:0:
|
||||||
|
94,147,95762,5,0,0:0:0:0:
|
||||||
|
160,126,95873,5,0,3:0:0:0:
|
||||||
|
231,149,95984,5,0,0:0:0:0:
|
||||||
|
273,221,96096,5,4,0:0:0:0:
|
||||||
|
353,262,96207,5,0,0:0:0:0:
|
||||||
|
446,234,96318,5,8,3:0:0:0:
|
||||||
|
501,145,96429,5,0,0:0:0:0:
|
||||||
|
450,36,96540,5,4,0:0:0:0:
|
||||||
|
239,44,96762,5,0,3:0:0:0:
|
||||||
|
192,103,96873,1,0,0:0:0:0:
|
||||||
|
118,118,96984,1,4,0:0:0:0:
|
||||||
|
44,100,97096,1,0,0:0:0:0:
|
||||||
|
5,36,97207,1,8,3:0:0:0:
|
||||||
|
17,19,97429,37,4,0:0:0:0:
|
||||||
|
146,51,97540,1,0,0:0:0:0:
|
||||||
|
29,122,97651,2,0,L|39:193,1,56.2499991059302,0|0,3:0|0:0,0:0:0:0:
|
||||||
|
44,197,97874,6,0,P|100:231|176:201,1,112.500002503395,4|0,0:0|0:0,0:0:0:0:
|
||||||
|
301,160,98096,38,0,P|329:140|382:137,1,84.3750018775463,8|0,3:0|0:0,0:0:0:0:
|
||||||
|
398,147,98318,6,0,B|431:187|431:187|415:279,1,112.500002503395,4|0,0:0|0:0,0:0:0:0:
|
||||||
|
265,371,98540,38,0,L|180:361,1,74.999998807907,0|0,3:0|0:0,0:0:0:0:
|
||||||
|
127,202,98762,2,0,L|141:113,1,74.999998807907,4|0,0:0|0:0,0:0:0:0:
|
||||||
|
193,260,98985,2,0,P|144:291|68:278,1,112.49999821186,8|0,3:0|0:0,0:0:0:0:
|
||||||
|
91,290,99207,2,0,L|79:373,1,74.999998807907,4|0,0:0|0:0,0:0:0:0:
|
||||||
|
20,184,99429,6,0,B|4:141|4:141|27:66,1,112.49999821186,0|0,3:0|0:0,0:0:0:0:
|
||||||
|
23,78,99651,2,0,L|109:91,1,74.999998807907,4|0,0:0|0:0,0:0:0:0:
|
||||||
|
271,74,99874,2,0,P|254:31|222:12,1,74.999998807907,8|0,3:0|0:0,0:0:0:0:
|
||||||
|
186,180,100096,2,0,P|232:175|260:147,1,74.999998807907,4|0,0:0|0:0,0:0:0:0:
|
||||||
|
132,63,100318,37,0,3:0:0:0:
|
||||||
|
253,157,100540,1,4,0:0:0:0:
|
||||||
|
285,167,100651,1,0,0:0:0:0:
|
||||||
|
357,129,100762,5,8,3:0:0:0:
|
||||||
|
389,139,100873,1,0,0:0:0:0:
|
||||||
|
422,148,100985,2,0,P|407:200|416:233,1,74.999998807907,4|0,0:0|0:0,0:0:0:0:
|
||||||
|
459,377,101207,38,0,P|472:333|459:295,1,74.999998807907,0|0,3:0|0:0,0:0:0:0:
|
||||||
|
398,242,101429,2,0,L|314:257,1,74.999998807907,4|0,0:0|0:0,0:0:0:0:
|
||||||
|
165,354,101651,2,0,P|116:332|211:264,1,224.999996423721,8|0,3:0|0:0,0:0:0:0:
|
||||||
|
302,165,102096,6,0,L|292:89,1,74.999998807907,0|0,3:0|0:0,0:0:0:0:
|
||||||
|
392,91,102318,2,0,L|382:14,1,74.999998807907,4|0,0:0|0:0,0:0:0:0:
|
||||||
|
192,229,102540,38,0,L|212:136,1,74.999998807907,8|0,3:0|0:0,0:0:0:0:
|
||||||
|
107,172,102762,2,0,L|127:79,1,74.999998807907,4|0,0:0|0:0,0:0:0:0:
|
||||||
|
314,332,102985,6,0,L|305:278,1,37.4999994039535,0|0,3:0|0:0,0:0:0:0:
|
||||||
|
343,345,103096,2,0,L|334:291,1,37.4999994039535,0|0,0:0|0:0,0:0:0:0:
|
||||||
|
370,358,103207,2,0,L|361:304,1,37.4999994039535,4|0,0:0|0:0,0:0:0:0:
|
||||||
|
380,117,103429,38,0,L|374:75,3,37.4999994039535,8|0|0|0,3:0|0:0|0:0|0:0,0:0:0:0:
|
||||||
|
444,166,103651,2,0,P|417:188|346:191,1,74.999998807907,4|0,0:0|0:0,0:0:0:0:
|
||||||
|
392,2,103874,2,0,P|424:14|462:74,1,74.999998807907,4|0,3:0|0:0,0:0:0:0:
|
||||||
|
271,129,104096,2,0,P|265:94|298:31,1,74.999998807907,4|0,0:0|0:0,0:0:0:0:
|
||||||
|
505,113,104318,5,8,3:0:0:0:
|
||||||
|
269,217,104540,38,0,L|216:216,3,37.4999994039535,0|0|0|0,3:0|3:0|3:0|3:0,0:0:0:0:
|
||||||
|
360,220,104762,1,0,3:0:0:0:
|
||||||
|
296,384,104874,1,4,3:0:0:0:
|
||||||
|
102,307,105096,5,0,0:0:0:0:
|
||||||
|
102,307,105207,2,0,B|206:381|258:244|374:330,1,269.999987468719,12|0,3:0|0:0,0:0:0:0:
|
||||||
|
439,319,105651,6,0,P|379:336|396:236,1,168.750003755093,0|0,3:0|0:0,0:0:0:0:
|
||||||
|
373,258,106096,6,0,P|374:315|443:283,1,112.500002503395,8|0,3:0|0:0,0:0:0:0:
|
||||||
|
420,323,106651,37,0,0:0:0:0:
|
||||||
|
469,245,106763,1,4,0:0:0:0:
|
||||||
|
508,322,106874,1,0,0:0:0:0:
|
||||||
|
379,245,106985,1,8,3:0:0:0:
|
||||||
|
483,105,107207,6,0,L|474:40,3,56.2500012516975,4|0|0|0,3:0|0:0|0:0|0:0,0:0:0:0:
|
||||||
|
462,30,107429,38,0,P|401:56|319:25,1,149.999997615814,0|0,3:0|0:0,0:0:0:0:
|
||||||
|
272,120,107874,2,0,P|184:91|118:125,1,149.999997615814,8|4,3:0|0:0,0:0:0:0:
|
||||||
|
103,213,108207,2,0,B|128:232|128:232|269:200,1,149.999997615814,0|0,0:0|0:0,0:0:0:0:
|
||||||
|
393,187,108540,2,0,L|385:286,1,74.999998807907,4|0,0:0|0:0,0:0:0:0:
|
||||||
|
333,338,108763,1,8,3:0:0:0:
|
||||||
|
467,307,108874,6,0,L|509:297,2,37.4999994039535,0|0|4,0:0|0:0|0:0,0:0:0:0:
|
||||||
|
409,380,109096,1,0,0:0:0:0:
|
||||||
|
300,257,109207,38,0,P|279:218|281:171,1,74.999998807907,0|0,3:0|0:0,0:0:0:0:
|
||||||
|
401,118,109429,1,4,0:0:0:0:
|
||||||
|
401,118,109651,6,0,L|315:109,1,74.999998807907,8|4,3:0|0:0,0:0:0:0:
|
||||||
|
256,15,109985,37,0,0:0:0:0:
|
||||||
|
175,121,110096,2,0,P|162:60|109:16,1,112.49999821186,0|0,3:0|0:0,0:0:0:0:
|
||||||
|
128,26,110318,2,0,P|106:86|47:122,1,112.49999821186,0|0,0:0|0:0,0:0:0:0:
|
||||||
|
69,114,110540,2,0,P|135:105|185:131,1,112.49999821186,8|0,3:0|0:0,0:0:0:0:
|
||||||
|
160,223,110762,6,0,B|142:230|142:230|120:228|120:228|95:239|95:239|71:235|71:235|49:244|49:244|22:249,1,112.500002503395,4|0,0:0|0:0,0:0:0:0:
|
||||||
|
193,334,110985,38,0,P|216:310|242:301,1,56.2500012516975,0|0,3:0|0:0,0:0:0:0:
|
||||||
|
335,325,111207,2,0,P|366:353|378:379,1,56.2500012516975,0|0,0:0|0:0,0:0:0:0:
|
||||||
|
273,383,111429,2,0,L|304:213,1,168.750003755093,0|0,0:0|0:0,0:0:0:0:
|
||||||
|
383,255,111874,22,0,B|422:273|422:273|476:273,1,74.999998807907,8|0,3:0|3:0,0:0:0:0:
|
||||||
|
209,219,112096,2,0,B|169:221|169:221|131:206,1,74.999998807907,0|0,0:0|0:0,0:0:0:0:
|
||||||
|
403,147,112318,2,0,B|352:114|352:114|337:43|337:43|295:109|295:109|234:115,1,269.999987468719,8|0,3:0|0:0,0:0:0:0:
|
||||||
File diff suppressed because one or more lines are too long
1213
osu.Game.Rulesets.Osu.Tests/Resources/Testing/Beatmaps/2593923.osu
Normal file
1213
osu.Game.Rulesets.Osu.Tests/Resources/Testing/Beatmaps/2593923.osu
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
1768
osu.Game.Rulesets.Osu.Tests/Resources/Testing/Beatmaps/801165.osu
Normal file
1768
osu.Game.Rulesets.Osu.Tests/Resources/Testing/Beatmaps/801165.osu
Normal file
File diff suppressed because it is too large
Load Diff
@@ -4,7 +4,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.IO;
|
using osu.Game.IO;
|
||||||
@@ -19,23 +18,9 @@ namespace osu.Game.Rulesets.Osu.Tests
|
|||||||
public class StackingTest
|
public class StackingTest
|
||||||
{
|
{
|
||||||
[Test]
|
[Test]
|
||||||
public void TestStacking()
|
public void TestStackingEdgeCaseOne()
|
||||||
{
|
{
|
||||||
using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(beatmap_data)))
|
using (var stream = new MemoryStream(@"
|
||||||
using (var reader = new LineBufferedReader(stream))
|
|
||||||
{
|
|
||||||
var beatmap = Decoder.GetDecoder<Beatmap>(reader).Decode(reader);
|
|
||||||
var converted = new TestWorkingBeatmap(beatmap).GetPlayableBeatmap(new OsuRuleset().RulesetInfo, Array.Empty<Mod>());
|
|
||||||
|
|
||||||
var objects = converted.HitObjects.ToList();
|
|
||||||
|
|
||||||
// The last hitobject triggers the stacking
|
|
||||||
for (int i = 0; i < objects.Count - 1; i++)
|
|
||||||
Assert.AreEqual(0, ((OsuHitObject)objects[i]).StackHeight);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private const string beatmap_data = @"
|
|
||||||
osu file format v14
|
osu file format v14
|
||||||
|
|
||||||
[General]
|
[General]
|
||||||
@@ -62,6 +47,65 @@ SliderTickRate:0.5
|
|||||||
311,185,218471,2,0,L|325:209,1,25
|
311,185,218471,2,0,L|325:209,1,25
|
||||||
311,185,218671,2,0,L|304:212,1,25
|
311,185,218671,2,0,L|304:212,1,25
|
||||||
311,185,240271,5,0,0:0:0:0:
|
311,185,240271,5,0,0:0:0:0:
|
||||||
";
|
"u8.ToArray()))
|
||||||
|
using (var reader = new LineBufferedReader(stream))
|
||||||
|
{
|
||||||
|
var beatmap = Decoder.GetDecoder<Beatmap>(reader).Decode(reader);
|
||||||
|
var converted = new TestWorkingBeatmap(beatmap).GetPlayableBeatmap(new OsuRuleset().RulesetInfo, Array.Empty<Mod>());
|
||||||
|
|
||||||
|
var objects = converted.HitObjects.ToList();
|
||||||
|
|
||||||
|
// The last hitobject triggers the stacking
|
||||||
|
for (int i = 0; i < objects.Count - 1; i++)
|
||||||
|
Assert.AreEqual(0, ((OsuHitObject)objects[i]).StackHeight);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestStackingEdgeCaseTwo()
|
||||||
|
{
|
||||||
|
using (var stream = new MemoryStream(@"
|
||||||
|
osu file format v14
|
||||||
|
// extracted from https://osu.ppy.sh/beatmapsets/365006#osu/801165
|
||||||
|
|
||||||
|
[General]
|
||||||
|
StackLeniency: 0.2
|
||||||
|
|
||||||
|
[Difficulty]
|
||||||
|
HPDrainRate:6
|
||||||
|
CircleSize:4
|
||||||
|
OverallDifficulty:8
|
||||||
|
ApproachRate:9.3
|
||||||
|
SliderMultiplier:2
|
||||||
|
SliderTickRate:1
|
||||||
|
|
||||||
|
[TimingPoints]
|
||||||
|
5338,444.444444444444,4,2,0,50,1,0
|
||||||
|
82893,-76.9230769230769,4,2,8,50,0,0
|
||||||
|
85115,-76.9230769230769,4,2,0,50,0,0
|
||||||
|
85337,-100,4,2,8,60,0,0
|
||||||
|
85893,-100,4,2,7,60,0,0
|
||||||
|
86226,-100,4,2,8,60,0,0
|
||||||
|
88893,-58.8235294117647,4,1,8,70,0,1
|
||||||
|
|
||||||
|
[HitObjects]
|
||||||
|
427,124,84226,1,0,3:0:0:0:
|
||||||
|
427,124,84337,1,0,3:0:0:0:
|
||||||
|
427,124,84449,1,8,0:0:0:0:
|
||||||
|
"u8.ToArray()))
|
||||||
|
using (var reader = new LineBufferedReader(stream))
|
||||||
|
{
|
||||||
|
var beatmap = Decoder.GetDecoder<Beatmap>(reader).Decode(reader);
|
||||||
|
var converted = new TestWorkingBeatmap(beatmap).GetPlayableBeatmap(new OsuRuleset().RulesetInfo, Array.Empty<Mod>());
|
||||||
|
|
||||||
|
var objects = converted.HitObjects.ToList();
|
||||||
|
|
||||||
|
Assert.That(objects, Has.Count.EqualTo(3));
|
||||||
|
|
||||||
|
// The last hitobject triggers the stacking
|
||||||
|
for (int i = 0; i < objects.Count - 1; i++)
|
||||||
|
Assert.AreEqual(0, ((OsuHitObject)objects[i]).StackHeight);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
63
osu.Game.Rulesets.Osu.Tests/TestSceneAutoGeneration.cs
Normal file
63
osu.Game.Rulesets.Osu.Tests/TestSceneAutoGeneration.cs
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
|
using System.Linq;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using osu.Framework.Testing;
|
||||||
|
using osu.Game.Rulesets.Osu.Beatmaps;
|
||||||
|
using osu.Game.Rulesets.Osu.Objects;
|
||||||
|
using osu.Game.Rulesets.Osu.Replays;
|
||||||
|
using osu.Game.Rulesets.Replays;
|
||||||
|
using osu.Game.Tests.Visual;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Osu.Tests
|
||||||
|
{
|
||||||
|
[TestFixture]
|
||||||
|
[HeadlessTest]
|
||||||
|
public partial class TestSceneAutoGeneration : OsuTestScene
|
||||||
|
{
|
||||||
|
[TestCase(-1, true)]
|
||||||
|
[TestCase(0, false)]
|
||||||
|
[TestCase(1, false)]
|
||||||
|
public void TestAlternating(double offset, bool shouldAlternate)
|
||||||
|
{
|
||||||
|
const double first_object_time = 1000;
|
||||||
|
double secondObjectTime = first_object_time + AutoGenerator.KEY_UP_DELAY + OsuAutoGenerator.MIN_FRAME_SEPARATION_FOR_ALTERNATING + offset;
|
||||||
|
|
||||||
|
var beatmap = new OsuBeatmap();
|
||||||
|
beatmap.HitObjects.Add(new HitCircle { StartTime = first_object_time });
|
||||||
|
beatmap.HitObjects.Add(new HitCircle { StartTime = secondObjectTime });
|
||||||
|
|
||||||
|
var generated = new OsuAutoGenerator(beatmap, []).Generate();
|
||||||
|
var frames = generated.Frames.OfType<OsuReplayFrame>().ToList();
|
||||||
|
|
||||||
|
Assert.That(frames.Exists(f => f.Time == first_object_time && f.Actions.SingleOrDefault() == OsuAction.LeftButton));
|
||||||
|
Assert.That(frames.Exists(f => f.Time == first_object_time + AutoGenerator.KEY_UP_DELAY && !f.Actions.Any()));
|
||||||
|
|
||||||
|
Assert.That(frames.Exists(f => f.Time == secondObjectTime && f.Actions.SingleOrDefault() == (shouldAlternate ? OsuAction.RightButton : OsuAction.LeftButton)));
|
||||||
|
Assert.That(frames.Exists(f => f.Time == secondObjectTime + AutoGenerator.KEY_UP_DELAY && !f.Actions.Any()));
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestCase(300)]
|
||||||
|
[TestCase(600)]
|
||||||
|
[TestCase(1200)]
|
||||||
|
public void TestAlternatingSpecificBPM(double bpm)
|
||||||
|
{
|
||||||
|
const double first_object_time = 1000;
|
||||||
|
double secondObjectTime = first_object_time + 60000 / bpm;
|
||||||
|
|
||||||
|
var beatmap = new OsuBeatmap();
|
||||||
|
beatmap.HitObjects.Add(new HitCircle { StartTime = first_object_time });
|
||||||
|
beatmap.HitObjects.Add(new HitCircle { StartTime = secondObjectTime });
|
||||||
|
|
||||||
|
var generated = new OsuAutoGenerator(beatmap, []).Generate();
|
||||||
|
var frames = generated.Frames.OfType<OsuReplayFrame>().ToList();
|
||||||
|
|
||||||
|
Assert.That(frames.Exists(f => f.Time == first_object_time && f.Actions.SingleOrDefault() == OsuAction.LeftButton));
|
||||||
|
Assert.That(frames.Exists(f => f.Time == first_object_time + AutoGenerator.KEY_UP_DELAY && !f.Actions.Any()));
|
||||||
|
|
||||||
|
Assert.That(frames.Exists(f => f.Time == secondObjectTime && f.Actions.SingleOrDefault() == OsuAction.RightButton));
|
||||||
|
Assert.That(frames.Exists(f => f.Time == secondObjectTime + AutoGenerator.KEY_UP_DELAY && !f.Actions.Any()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -33,7 +33,7 @@ namespace osu.Game.Rulesets.Osu.Tests
|
|||||||
Debug.Assert(drawableHitObject.HitObject.HitWindows != null);
|
Debug.Assert(drawableHitObject.HitObject.HitWindows != null);
|
||||||
|
|
||||||
double delay = drawableHitObject.HitObject.StartTime - (drawableHitObject.HitObject.HitWindows.WindowFor(HitResult.Miss) + RNG.Next(0, 300)) - Time.Current;
|
double delay = drawableHitObject.HitObject.StartTime - (drawableHitObject.HitObject.HitWindows.WindowFor(HitResult.Miss) + RNG.Next(0, 300)) - Time.Current;
|
||||||
scheduledTasks.Add(Scheduler.AddDelayed(() => drawableHitObject.TriggerJudgement(), delay));
|
scheduledTasks.Add(Scheduler.AddDelayed(drawableHitObject.TriggerJudgement, delay));
|
||||||
|
|
||||||
return drawableHitObject;
|
return drawableHitObject;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -91,7 +91,7 @@ namespace osu.Game.Rulesets.Osu.Beatmaps
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
double endTime = stackBaseObject.GetEndTime();
|
double endTime = stackBaseObject.GetEndTime();
|
||||||
double stackThreshold = objectN.TimePreempt * beatmap.StackLeniency;
|
float stackThreshold = calculateStackThreshold(beatmap, objectN);
|
||||||
|
|
||||||
if (objectN.StartTime - endTime > stackThreshold)
|
if (objectN.StartTime - endTime > stackThreshold)
|
||||||
// We are no longer within stacking range of the next object.
|
// We are no longer within stacking range of the next object.
|
||||||
@@ -136,7 +136,7 @@ namespace osu.Game.Rulesets.Osu.Beatmaps
|
|||||||
OsuHitObject objectI = hitObjects[i];
|
OsuHitObject objectI = hitObjects[i];
|
||||||
if (objectI.StackHeight != 0 || objectI is Spinner) continue;
|
if (objectI.StackHeight != 0 || objectI is Spinner) continue;
|
||||||
|
|
||||||
double stackThreshold = objectI.TimePreempt * beatmap.StackLeniency;
|
float stackThreshold = calculateStackThreshold(beatmap, objectI);
|
||||||
|
|
||||||
/* If this object is a hitcircle, then we enter this "special" case.
|
/* If this object is a hitcircle, then we enter this "special" case.
|
||||||
* It either ends with a stack of hitcircles only, or a stack of hitcircles that are underneath a slider.
|
* It either ends with a stack of hitcircles only, or a stack of hitcircles that are underneath a slider.
|
||||||
@@ -151,7 +151,10 @@ namespace osu.Game.Rulesets.Osu.Beatmaps
|
|||||||
|
|
||||||
double endTime = objectN.GetEndTime();
|
double endTime = objectN.GetEndTime();
|
||||||
|
|
||||||
if (objectI.StartTime - endTime > stackThreshold)
|
// truncation to integer is required to match stable
|
||||||
|
// compare https://github.com/peppy/osu-stable-reference/blob/08e3dafd525934cf48880b08e91c24ce4ad8b761/osu!/GameplayElements/HitObjectManager.cs#L1725
|
||||||
|
// - both quantities being subtracted there are integers
|
||||||
|
if ((int)objectI.StartTime - (int)endTime > stackThreshold)
|
||||||
// We are no longer within stacking range of the previous object.
|
// We are no longer within stacking range of the previous object.
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -232,7 +235,7 @@ namespace osu.Game.Rulesets.Osu.Beatmaps
|
|||||||
|
|
||||||
for (int j = i + 1; j < hitObjects.Count; j++)
|
for (int j = i + 1; j < hitObjects.Count; j++)
|
||||||
{
|
{
|
||||||
double stackThreshold = hitObjects[i].TimePreempt * beatmap.StackLeniency;
|
float stackThreshold = calculateStackThreshold(beatmap, hitObjects[i]);
|
||||||
|
|
||||||
if (hitObjects[j].StartTime - stackThreshold > startTime)
|
if (hitObjects[j].StartTime - stackThreshold > startTime)
|
||||||
break;
|
break;
|
||||||
@@ -264,5 +267,17 @@ namespace osu.Game.Rulesets.Osu.Beatmaps
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <remarks>
|
||||||
|
/// Truncation of <see cref="OsuHitObject.TimePreempt"/> to <see cref="int"/>, as well as keeping the result as <see cref="float"/>, are both done
|
||||||
|
/// <a href="https://github.com/peppy/osu-stable-reference/blob/08e3dafd525934cf48880b08e91c24ce4ad8b761/osu!/GameplayElements/HitObjectManager.cs#L1652">
|
||||||
|
/// for the purposes of stable compatibility
|
||||||
|
/// </a>.
|
||||||
|
/// Note that for top-level objects <see cref="OsuHitObject.TimePreempt"/> is supposed to be integral anyway;
|
||||||
|
/// see <see cref="OsuHitObject.ApplyDefaultsToSelf"/> using <see cref="IBeatmapDifficultyInfo.DifficultyRangeInt"/> when calculating it.
|
||||||
|
/// Slider ticks and end circles are the exception to that, but they do not matter for stacking.
|
||||||
|
/// </remarks>
|
||||||
|
private static float calculateStackThreshold(IBeatmap beatmap, OsuHitObject hitObject)
|
||||||
|
=> (int)hitObject.TimePreempt * beatmap.StackLeniency;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ using System.Diagnostics;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Bindables;
|
using osu.Framework.Bindables;
|
||||||
|
using osu.Framework.Extensions.ObjectExtensions;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Primitives;
|
using osu.Framework.Graphics.Primitives;
|
||||||
using osu.Framework.Utils;
|
using osu.Framework.Utils;
|
||||||
@@ -37,13 +38,16 @@ namespace osu.Game.Rulesets.Osu.Edit
|
|||||||
[Resolved]
|
[Resolved]
|
||||||
private IEditorChangeHandler? changeHandler { get; set; }
|
private IEditorChangeHandler? changeHandler { get; set; }
|
||||||
|
|
||||||
|
[Resolved]
|
||||||
|
private EditorBeatmap editorBeatmap { get; set; } = null!;
|
||||||
|
|
||||||
[Resolved(CanBeNull = true)]
|
[Resolved(CanBeNull = true)]
|
||||||
private IDistanceSnapProvider? snapProvider { get; set; }
|
private IDistanceSnapProvider? snapProvider { get; set; }
|
||||||
|
|
||||||
private BindableList<HitObject> selectedItems { get; } = new BindableList<HitObject>();
|
private BindableList<HitObject> selectedItems { get; } = new BindableList<HitObject>();
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load(EditorBeatmap editorBeatmap)
|
private void load()
|
||||||
{
|
{
|
||||||
selectedItems.BindTo(editorBeatmap.SelectedHitObjects);
|
selectedItems.BindTo(editorBeatmap.SelectedHitObjects);
|
||||||
}
|
}
|
||||||
@@ -53,15 +57,22 @@ namespace osu.Game.Rulesets.Osu.Edit
|
|||||||
base.LoadComplete();
|
base.LoadComplete();
|
||||||
|
|
||||||
selectedItems.CollectionChanged += (_, __) => updateState();
|
selectedItems.CollectionChanged += (_, __) => updateState();
|
||||||
|
editorBeatmap.HitObjectUpdated += hitObjectUpdated;
|
||||||
updateState();
|
updateState();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void hitObjectUpdated(HitObject hitObject)
|
||||||
|
{
|
||||||
|
if (selectedMovableObjects.Contains(hitObject))
|
||||||
|
updateState();
|
||||||
|
}
|
||||||
|
|
||||||
private void updateState()
|
private void updateState()
|
||||||
{
|
{
|
||||||
var quad = GeometryUtils.GetSurroundingQuad(selectedMovableObjects);
|
var quad = GeometryUtils.GetSurroundingQuad(selectedMovableObjects);
|
||||||
|
|
||||||
CanScaleX.Value = quad.Width > 0;
|
CanScaleX.Value = Precision.DefinitelyBigger(quad.Width, 0);
|
||||||
CanScaleY.Value = quad.Height > 0;
|
CanScaleY.Value = Precision.DefinitelyBigger(quad.Height, 0);
|
||||||
CanScaleDiagonally.Value = CanScaleX.Value && CanScaleY.Value;
|
CanScaleDiagonally.Value = CanScaleX.Value && CanScaleY.Value;
|
||||||
CanScaleFromPlayfieldOrigin.Value = selectedMovableObjects.Any();
|
CanScaleFromPlayfieldOrigin.Value = selectedMovableObjects.Any();
|
||||||
IsScalingSlider.Value = selectedMovableObjects.Count() == 1 && selectedMovableObjects.First() is Slider;
|
IsScalingSlider.Value = selectedMovableObjects.Count() == 1 && selectedMovableObjects.First() is Slider;
|
||||||
@@ -339,5 +350,13 @@ namespace osu.Game.Rulesets.Osu.Edit
|
|||||||
PathControlPointTypes = (hitObject as IHasPath)?.Path.ControlPoints.Select(p => p.Type).ToArray();
|
PathControlPointTypes = (hitObject as IHasPath)?.Path.ControlPoints.Select(p => p.Type).ToArray();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override void Dispose(bool isDisposing)
|
||||||
|
{
|
||||||
|
base.Dispose(isDisposing);
|
||||||
|
|
||||||
|
if (editorBeatmap.IsNotNull())
|
||||||
|
editorBeatmap.HitObjectUpdated -= hitObjectUpdated;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,10 +25,10 @@ namespace osu.Game.Rulesets.Osu.Edit
|
|||||||
{
|
{
|
||||||
public partial class PolygonGenerationPopover : OsuPopover
|
public partial class PolygonGenerationPopover : OsuPopover
|
||||||
{
|
{
|
||||||
private SliderWithTextBoxInput<double> distanceSnapInput = null!;
|
private FormSliderBar<double> distanceSnapInput { get; set; } = null!;
|
||||||
private SliderWithTextBoxInput<int> offsetAngleInput = null!;
|
private FormSliderBar<int> offsetAngleInput { get; set; } = null!;
|
||||||
private SliderWithTextBoxInput<int> repeatCountInput = null!;
|
private FormSliderBar<int> repeatCountInput { get; set; } = null!;
|
||||||
private SliderWithTextBoxInput<int> pointInput = null!;
|
private FormSliderBar<int> pointInput { get; set; } = null!;
|
||||||
private RoundedButton commitButton = null!;
|
private RoundedButton commitButton = null!;
|
||||||
|
|
||||||
private readonly List<HitCircle> insertedCircles = new List<HitCircle>();
|
private readonly List<HitCircle> insertedCircles = new List<HitCircle>();
|
||||||
@@ -64,11 +64,12 @@ namespace osu.Game.Rulesets.Osu.Edit
|
|||||||
{
|
{
|
||||||
Width = 220,
|
Width = 220,
|
||||||
AutoSizeAxes = Axes.Y,
|
AutoSizeAxes = Axes.Y,
|
||||||
Spacing = new Vector2(20),
|
Spacing = new Vector2(5),
|
||||||
Children = new Drawable[]
|
Children = new Drawable[]
|
||||||
{
|
{
|
||||||
distanceSnapInput = new SliderWithTextBoxInput<double>("Distance snap:")
|
distanceSnapInput = new FormSliderBar<double>
|
||||||
{
|
{
|
||||||
|
Caption = "Distance snap",
|
||||||
Current = new BindableNumber<double>(1)
|
Current = new BindableNumber<double>(1)
|
||||||
{
|
{
|
||||||
MinValue = 0.1,
|
MinValue = 0.1,
|
||||||
@@ -76,37 +77,40 @@ namespace osu.Game.Rulesets.Osu.Edit
|
|||||||
Precision = 0.1,
|
Precision = 0.1,
|
||||||
Value = ((OsuHitObjectComposer)composer).DistanceSnapProvider.DistanceSpacingMultiplier.Value,
|
Value = ((OsuHitObjectComposer)composer).DistanceSnapProvider.DistanceSpacingMultiplier.Value,
|
||||||
},
|
},
|
||||||
Instantaneous = true
|
TabbableContentContainer = this
|
||||||
},
|
},
|
||||||
offsetAngleInput = new SliderWithTextBoxInput<int>("Offset angle:")
|
offsetAngleInput = new FormSliderBar<int>
|
||||||
{
|
{
|
||||||
|
Caption = "Offset angle",
|
||||||
Current = new BindableNumber<int>
|
Current = new BindableNumber<int>
|
||||||
{
|
{
|
||||||
MinValue = 0,
|
MinValue = 0,
|
||||||
MaxValue = 180,
|
MaxValue = 180,
|
||||||
Precision = 1
|
Precision = 1
|
||||||
},
|
},
|
||||||
Instantaneous = true
|
TabbableContentContainer = this
|
||||||
},
|
},
|
||||||
repeatCountInput = new SliderWithTextBoxInput<int>("Repeats:")
|
repeatCountInput = new FormSliderBar<int>
|
||||||
{
|
{
|
||||||
|
Caption = "Repeats",
|
||||||
Current = new BindableNumber<int>(1)
|
Current = new BindableNumber<int>(1)
|
||||||
{
|
{
|
||||||
MinValue = 1,
|
MinValue = 1,
|
||||||
MaxValue = 10,
|
MaxValue = 10,
|
||||||
Precision = 1
|
Precision = 1
|
||||||
},
|
},
|
||||||
Instantaneous = true
|
TabbableContentContainer = this
|
||||||
},
|
},
|
||||||
pointInput = new SliderWithTextBoxInput<int>("Vertices:")
|
pointInput = new FormSliderBar<int>
|
||||||
{
|
{
|
||||||
|
Caption = "Vertices",
|
||||||
Current = new BindableNumber<int>(3)
|
Current = new BindableNumber<int>(3)
|
||||||
{
|
{
|
||||||
MinValue = 3,
|
MinValue = 3,
|
||||||
MaxValue = 32,
|
MaxValue = 32,
|
||||||
Precision = 1,
|
Precision = 1,
|
||||||
},
|
},
|
||||||
Instantaneous = true
|
TabbableContentContainer = this
|
||||||
},
|
},
|
||||||
commitButton = new RoundedButton
|
commitButton = new RoundedButton
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ namespace osu.Game.Rulesets.Osu.Edit
|
|||||||
private BindableNumber<float> xBindable = null!;
|
private BindableNumber<float> xBindable = null!;
|
||||||
private BindableNumber<float> yBindable = null!;
|
private BindableNumber<float> yBindable = null!;
|
||||||
|
|
||||||
private SliderWithTextBoxInput<float> xInput = null!;
|
private FormSliderBar<float> xInput { get; set; } = null!;
|
||||||
private OsuCheckbox relativeCheckbox = null!;
|
private OsuCheckbox relativeCheckbox = null!;
|
||||||
|
|
||||||
public PreciseMovementPopover()
|
public PreciseMovementPopover()
|
||||||
@@ -52,31 +52,31 @@ namespace osu.Game.Rulesets.Osu.Edit
|
|||||||
{
|
{
|
||||||
Width = 220,
|
Width = 220,
|
||||||
AutoSizeAxes = Axes.Y,
|
AutoSizeAxes = Axes.Y,
|
||||||
Spacing = new Vector2(20),
|
Spacing = new Vector2(5),
|
||||||
Children = new Drawable[]
|
Children = new Drawable[]
|
||||||
{
|
{
|
||||||
xInput = new SliderWithTextBoxInput<float>("X:")
|
xInput = new FormSliderBar<float>
|
||||||
{
|
{
|
||||||
|
Caption = "X",
|
||||||
Current = xBindable = new BindableNumber<float>
|
Current = xBindable = new BindableNumber<float>
|
||||||
{
|
{
|
||||||
Precision = 1,
|
Precision = 1,
|
||||||
},
|
},
|
||||||
Instantaneous = true,
|
TabbableContentContainer = this
|
||||||
TabbableContentContainer = this,
|
|
||||||
},
|
},
|
||||||
new SliderWithTextBoxInput<float>("Y:")
|
new FormSliderBar<float>
|
||||||
{
|
{
|
||||||
|
Caption = "Y",
|
||||||
Current = yBindable = new BindableNumber<float>
|
Current = yBindable = new BindableNumber<float>
|
||||||
{
|
{
|
||||||
Precision = 1,
|
Precision = 1,
|
||||||
},
|
},
|
||||||
Instantaneous = true,
|
TabbableContentContainer = this
|
||||||
TabbableContentContainer = this,
|
|
||||||
},
|
},
|
||||||
relativeCheckbox = new OsuCheckbox(false)
|
relativeCheckbox = new OsuCheckbox(false)
|
||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.X,
|
RelativeSizeAxes = Axes.X,
|
||||||
LabelText = "Relative movement",
|
LabelText = "Relative movement"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ namespace osu.Game.Rulesets.Osu.Edit
|
|||||||
|
|
||||||
private readonly Bindable<PreciseRotationInfo> rotationInfo = new Bindable<PreciseRotationInfo>(new PreciseRotationInfo(0, EditorOrigin.GridCentre));
|
private readonly Bindable<PreciseRotationInfo> rotationInfo = new Bindable<PreciseRotationInfo>(new PreciseRotationInfo(0, EditorOrigin.GridCentre));
|
||||||
|
|
||||||
private SliderWithTextBoxInput<float> angleInput = null!;
|
private FormSliderBar<float> angleInput { get; set; } = null!;
|
||||||
private EditorRadioButtonCollection rotationOrigin = null!;
|
private EditorRadioButtonCollection rotationOrigin = null!;
|
||||||
|
|
||||||
private RadioButton gridCentreButton = null!;
|
private RadioButton gridCentreButton = null!;
|
||||||
@@ -54,11 +54,12 @@ namespace osu.Game.Rulesets.Osu.Edit
|
|||||||
{
|
{
|
||||||
Width = 220,
|
Width = 220,
|
||||||
AutoSizeAxes = Axes.Y,
|
AutoSizeAxes = Axes.Y,
|
||||||
Spacing = new Vector2(20),
|
Spacing = new Vector2(5),
|
||||||
Children = new Drawable[]
|
Children = new Drawable[]
|
||||||
{
|
{
|
||||||
angleInput = new SliderWithTextBoxInput<float>("Angle (degrees):")
|
angleInput = new FormSliderBar<float>
|
||||||
{
|
{
|
||||||
|
Caption = "Angle (degrees)",
|
||||||
Current = new BindableNumber<float>
|
Current = new BindableNumber<float>
|
||||||
{
|
{
|
||||||
MinValue = -360,
|
MinValue = -360,
|
||||||
@@ -66,7 +67,7 @@ namespace osu.Game.Rulesets.Osu.Edit
|
|||||||
Precision = 1
|
Precision = 1
|
||||||
},
|
},
|
||||||
KeyboardStep = 1f,
|
KeyboardStep = 1f,
|
||||||
Instantaneous = true
|
TabbableContentContainer = this
|
||||||
},
|
},
|
||||||
rotationOrigin = new EditorRadioButtonCollection
|
rotationOrigin = new EditorRadioButtonCollection
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ namespace osu.Game.Rulesets.Osu.Edit
|
|||||||
|
|
||||||
private readonly Bindable<PreciseScaleInfo> scaleInfo = new Bindable<PreciseScaleInfo>(new PreciseScaleInfo(1, EditorOrigin.GridCentre, true, true));
|
private readonly Bindable<PreciseScaleInfo> scaleInfo = new Bindable<PreciseScaleInfo>(new PreciseScaleInfo(1, EditorOrigin.GridCentre, true, true));
|
||||||
|
|
||||||
private SliderWithTextBoxInput<float> scaleInput = null!;
|
private FormSliderBar<float> scaleInput { get; set; } = null!;
|
||||||
private BindableNumber<float> scaleInputBindable = null!;
|
private BindableNumber<float> scaleInputBindable = null!;
|
||||||
private EditorRadioButtonCollection scaleOrigin = null!;
|
private EditorRadioButtonCollection scaleOrigin = null!;
|
||||||
|
|
||||||
@@ -66,11 +66,12 @@ namespace osu.Game.Rulesets.Osu.Edit
|
|||||||
{
|
{
|
||||||
Width = 220,
|
Width = 220,
|
||||||
AutoSizeAxes = Axes.Y,
|
AutoSizeAxes = Axes.Y,
|
||||||
Spacing = new Vector2(20),
|
Spacing = new Vector2(5),
|
||||||
Children = new Drawable[]
|
Children = new Drawable[]
|
||||||
{
|
{
|
||||||
scaleInput = new SliderWithTextBoxInput<float>("Scale:")
|
scaleInput = new FormSliderBar<float>
|
||||||
{
|
{
|
||||||
|
Caption = "Scale",
|
||||||
Current = scaleInputBindable = new BindableNumber<float>
|
Current = scaleInputBindable = new BindableNumber<float>
|
||||||
{
|
{
|
||||||
MinValue = 0.05f,
|
MinValue = 0.05f,
|
||||||
@@ -80,7 +81,7 @@ namespace osu.Game.Rulesets.Osu.Edit
|
|||||||
Default = 1,
|
Default = 1,
|
||||||
},
|
},
|
||||||
KeyboardStep = 0.01f,
|
KeyboardStep = 0.01f,
|
||||||
Instantaneous = true
|
TabbableContentContainer = this
|
||||||
},
|
},
|
||||||
scaleOrigin = new EditorRadioButtonCollection
|
scaleOrigin = new EditorRadioButtonCollection
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -14,7 +14,13 @@ namespace osu.Game.Rulesets.Osu.Mods
|
|||||||
{
|
{
|
||||||
public override Type[] IncompatibleMods => base.IncompatibleMods.Concat(new[] { typeof(OsuModMagnetised), typeof(OsuModRepel), typeof(OsuModAutopilot), typeof(OsuModSpunOut), typeof(OsuModAlternate), typeof(OsuModSingleTap) }).ToArray();
|
public override Type[] IncompatibleMods => base.IncompatibleMods.Concat(new[] { typeof(OsuModMagnetised), typeof(OsuModRepel), typeof(OsuModAutopilot), typeof(OsuModSpunOut), typeof(OsuModAlternate), typeof(OsuModSingleTap) }).ToArray();
|
||||||
|
|
||||||
|
#if !DEBUG
|
||||||
|
private string username = "Autoplay";
|
||||||
|
#else
|
||||||
|
private string username = "Chicony";
|
||||||
|
#endif
|
||||||
|
|
||||||
public override ModReplayData CreateReplayData(IBeatmap beatmap, IReadOnlyList<Mod> mods)
|
public override ModReplayData CreateReplayData(IBeatmap beatmap, IReadOnlyList<Mod> mods)
|
||||||
=> new ModReplayData(new OsuAutoGenerator(beatmap, mods).Generate(), new ModCreatedUser { Username = "Autoplay" });
|
=> new ModReplayData(new OsuAutoGenerator(beatmap, mods).Generate(), new ModCreatedUser { Username = username });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ namespace osu.Game.Rulesets.Osu.Mods
|
|||||||
[SettingSource(
|
[SettingSource(
|
||||||
"Max size at combo",
|
"Max size at combo",
|
||||||
"The combo count at which the cursor reaches its maximum size",
|
"The combo count at which the cursor reaches its maximum size",
|
||||||
SettingControlType = typeof(SettingsSlider<int, RoundedSliderBar<int>>)
|
SettingControlType = typeof(SettingsSlider<int, MaxSizeComboSlider>)
|
||||||
)]
|
)]
|
||||||
public BindableInt MaxSizeComboCount { get; } = new BindableInt(50)
|
public BindableInt MaxSizeComboCount { get; } = new BindableInt(50)
|
||||||
{
|
{
|
||||||
@@ -85,4 +85,12 @@ namespace osu.Game.Rulesets.Osu.Mods
|
|||||||
cursor.ModScaleAdjust.Value = (float)Interpolation.Lerp(cursor.ModScaleAdjust.Value, currentSize, Math.Clamp(cursor.Time.Elapsed / TRANSITION_DURATION, 0, 1));
|
cursor.ModScaleAdjust.Value = (float)Interpolation.Lerp(cursor.ModScaleAdjust.Value, currentSize, Math.Clamp(cursor.Time.Elapsed / TRANSITION_DURATION, 0, 1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public partial class MaxSizeComboSlider : RoundedSliderBar<int>
|
||||||
|
{
|
||||||
|
public MaxSizeComboSlider()
|
||||||
|
{
|
||||||
|
KeyboardStep = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
using osu.Framework.Bindables;
|
using osu.Framework.Bindables;
|
||||||
using osu.Framework.Localisation;
|
using osu.Framework.Localisation;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
@@ -16,13 +18,19 @@ namespace osu.Game.Rulesets.Osu.Mods
|
|||||||
{
|
{
|
||||||
public partial class OsuModDifficultyAdjust : ModDifficultyAdjust
|
public partial class OsuModDifficultyAdjust : ModDifficultyAdjust
|
||||||
{
|
{
|
||||||
|
|
||||||
[SettingSource("Circle Size", "Override a beatmap's set CS.", FIRST_SETTING_ORDER - 1, SettingControlType = typeof(DifficultyAdjustSettingsControl))]
|
[SettingSource("Circle Size", "Override a beatmap's set CS.", FIRST_SETTING_ORDER - 1, SettingControlType = typeof(DifficultyAdjustSettingsControl))]
|
||||||
public DifficultyBindable CircleSize { get; } = new DifficultyBindable
|
public DifficultyBindable CircleSize { get; } = new DifficultyBindable
|
||||||
{
|
{
|
||||||
Precision = 0.1f,
|
Precision = 0.1f,
|
||||||
MinValue = 0,
|
MinValue = 0,
|
||||||
MaxValue = 10,
|
MaxValue = 10,
|
||||||
|
#if !DEBUG
|
||||||
ExtendedMaxValue = 11,
|
ExtendedMaxValue = 11,
|
||||||
|
#else
|
||||||
|
ExtendedMinValue = -250,
|
||||||
|
ExtendedMaxValue = 13,
|
||||||
|
#endif
|
||||||
ReadCurrentFromDifficulty = diff => diff.CircleSize,
|
ReadCurrentFromDifficulty = diff => diff.CircleSize,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -32,8 +40,13 @@ namespace osu.Game.Rulesets.Osu.Mods
|
|||||||
Precision = 0.1f,
|
Precision = 0.1f,
|
||||||
MinValue = 0,
|
MinValue = 0,
|
||||||
MaxValue = 10,
|
MaxValue = 10,
|
||||||
|
#if !DEBUG
|
||||||
ExtendedMinValue = -10,
|
ExtendedMinValue = -10,
|
||||||
ExtendedMaxValue = 11,
|
ExtendedMaxValue = 11,
|
||||||
|
#else
|
||||||
|
ExtendedMinValue = -250,
|
||||||
|
ExtendedMaxValue = 13,
|
||||||
|
#endif
|
||||||
ReadCurrentFromDifficulty = diff => diff.ApproachRate,
|
ReadCurrentFromDifficulty = diff => diff.ApproachRate,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -71,6 +84,8 @@ namespace osu.Game.Rulesets.Osu.Mods
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override Type[] IncompatibleMods => base.IncompatibleMods.Append(typeof(OsuModTargetPractice)).ToArray();
|
||||||
|
|
||||||
protected override void ApplySettings(BeatmapDifficulty difficulty)
|
protected override void ApplySettings(BeatmapDifficulty difficulty)
|
||||||
{
|
{
|
||||||
base.ApplySettings(difficulty);
|
base.ApplySettings(difficulty);
|
||||||
|
|||||||
@@ -27,8 +27,10 @@ namespace osu.Game.Rulesets.Osu.Mods
|
|||||||
|
|
||||||
public override LocalisableString Description => "Burn the notes into your memory.";
|
public override LocalisableString Description => "Burn the notes into your memory.";
|
||||||
|
|
||||||
//Alters the transforms of the approach circles, breaking the effects of these mods.
|
/// <remarks>
|
||||||
public override Type[] IncompatibleMods => base.IncompatibleMods.Concat(new[] { typeof(OsuModApproachDifferent), typeof(OsuModTransform), typeof(OsuModDepth) }).ToArray();
|
/// Incompatible with all mods that directly modify or indirectly depend on <see cref="OsuHitObject.TimePreempt"/>, or alter the behaviour of approach circles.
|
||||||
|
/// </remarks>
|
||||||
|
public override Type[] IncompatibleMods => base.IncompatibleMods.Concat(new[] { typeof(OsuModApproachDifferent), typeof(OsuModTransform), typeof(OsuModDepth), typeof(OsuModHidden) }).ToArray();
|
||||||
|
|
||||||
public override ModType Type => ModType.Fun;
|
public override ModType Type => ModType.Fun;
|
||||||
|
|
||||||
@@ -57,16 +59,25 @@ namespace osu.Game.Rulesets.Osu.Mods
|
|||||||
|
|
||||||
void applyFadeInAdjustment(OsuHitObject osuObject)
|
void applyFadeInAdjustment(OsuHitObject osuObject)
|
||||||
{
|
{
|
||||||
osuObject.TimePreempt += osuObject.StartTime - lastNewComboTime;
|
if (osuObject is not Spinner)
|
||||||
|
osuObject.TimePreempt += osuObject.StartTime - lastNewComboTime;
|
||||||
|
|
||||||
|
int repeatCount = 0;
|
||||||
|
|
||||||
foreach (var nested in osuObject.NestedHitObjects.OfType<OsuHitObject>())
|
foreach (var nested in osuObject.NestedHitObjects.OfType<OsuHitObject>())
|
||||||
{
|
{
|
||||||
switch (nested)
|
switch (nested)
|
||||||
{
|
{
|
||||||
//Freezing the SliderTicks doesnt play well with snaking sliders
|
// Freezing the SliderTicks doesnt play well with snaking sliders
|
||||||
case SliderTick:
|
case SliderTick:
|
||||||
//SliderRepeat wont layer correctly if preempt is changed.
|
break;
|
||||||
|
|
||||||
case SliderRepeat:
|
case SliderRepeat:
|
||||||
|
if (repeatCount > 2)
|
||||||
|
break;
|
||||||
|
|
||||||
|
applyFadeInAdjustment(nested);
|
||||||
|
repeatCount++;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ namespace osu.Game.Rulesets.Osu.Mods
|
|||||||
public override LocalisableString Description => @"Play with no approach circles and fading circles/sliders.";
|
public override LocalisableString Description => @"Play with no approach circles and fading circles/sliders.";
|
||||||
public override double ScoreMultiplier => UsesDefaultConfiguration ? 1.06 : 1;
|
public override double ScoreMultiplier => UsesDefaultConfiguration ? 1.06 : 1;
|
||||||
|
|
||||||
public override Type[] IncompatibleMods => new[] { typeof(IRequiresApproachCircles), typeof(OsuModSpinIn), typeof(OsuModDepth) };
|
public override Type[] IncompatibleMods => new[] { typeof(IRequiresApproachCircles), typeof(OsuModSpinIn), typeof(OsuModDepth), typeof(OsuModFreezeFrame) };
|
||||||
|
|
||||||
public const double FADE_IN_DURATION_MULTIPLIER = 0.4;
|
public const double FADE_IN_DURATION_MULTIPLIER = 0.4;
|
||||||
public const double FADE_OUT_DURATION_MULTIPLIER = 0.3;
|
public const double FADE_OUT_DURATION_MULTIPLIER = 0.3;
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ namespace osu.Game.Rulesets.Osu.Mods
|
|||||||
public override LocalisableString Description => @"Spinners will be automatically completed.";
|
public override LocalisableString Description => @"Spinners will be automatically completed.";
|
||||||
public override double ScoreMultiplier => 0.9;
|
public override double ScoreMultiplier => 0.9;
|
||||||
public override Type[] IncompatibleMods => new[] { typeof(ModAutoplay), typeof(OsuModAutopilot), typeof(OsuModTargetPractice) };
|
public override Type[] IncompatibleMods => new[] { typeof(ModAutoplay), typeof(OsuModAutopilot), typeof(OsuModTargetPractice) };
|
||||||
public override bool Ranked => UsesDefaultConfiguration;
|
public override bool Ranked => true;
|
||||||
|
|
||||||
public void ApplyToDrawableHitObject(DrawableHitObject hitObject)
|
public void ApplyToDrawableHitObject(DrawableHitObject hitObject)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -48,7 +48,8 @@ namespace osu.Game.Rulesets.Osu.Mods
|
|||||||
typeof(OsuModSpunOut),
|
typeof(OsuModSpunOut),
|
||||||
typeof(OsuModStrictTracking),
|
typeof(OsuModStrictTracking),
|
||||||
typeof(OsuModSuddenDeath),
|
typeof(OsuModSuddenDeath),
|
||||||
typeof(OsuModDepth)
|
typeof(OsuModDepth),
|
||||||
|
typeof(OsuModDifficultyAdjust),
|
||||||
}).ToArray();
|
}).ToArray();
|
||||||
|
|
||||||
[SettingSource("Seed", "Use a custom seed instead of a random one", SettingControlType = typeof(SettingsNumberBox))]
|
[SettingSource("Seed", "Use a custom seed instead of a random one", SettingControlType = typeof(SettingsNumberBox))]
|
||||||
|
|||||||
@@ -10,6 +10,6 @@ namespace osu.Game.Rulesets.Osu.Mods
|
|||||||
public class OsuModTouchDevice : ModTouchDevice
|
public class OsuModTouchDevice : ModTouchDevice
|
||||||
{
|
{
|
||||||
public override Type[] IncompatibleMods => base.IncompatibleMods.Concat(new[] { typeof(OsuModAutopilot), typeof(OsuModBloom) }).ToArray();
|
public override Type[] IncompatibleMods => base.IncompatibleMods.Concat(new[] { typeof(OsuModAutopilot), typeof(OsuModBloom) }).ToArray();
|
||||||
public override bool Ranked => UsesDefaultConfiguration;
|
public override bool Ranked => true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ namespace osu.Game.Rulesets.Osu.Mods
|
|||||||
public override string Name => "Traceable";
|
public override string Name => "Traceable";
|
||||||
public override string Acronym => "TC";
|
public override string Acronym => "TC";
|
||||||
public override IconUsage? Icon => OsuIcon.ModTraceable;
|
public override IconUsage? Icon => OsuIcon.ModTraceable;
|
||||||
public override ModType Type => ModType.Fun;
|
public override ModType Type => ModType.DifficultyIncrease;
|
||||||
public override LocalisableString Description => "Put your faith in the approach circles...";
|
public override LocalisableString Description => "Put your faith in the approach circles...";
|
||||||
public override double ScoreMultiplier => 1;
|
public override double ScoreMultiplier => 1;
|
||||||
public override bool Ranked => true;
|
public override bool Ranked => true;
|
||||||
|
|||||||
@@ -171,7 +171,7 @@ namespace osu.Game.Rulesets.Osu.Objects
|
|||||||
{
|
{
|
||||||
base.ApplyDefaultsToSelf(controlPointInfo, difficulty);
|
base.ApplyDefaultsToSelf(controlPointInfo, difficulty);
|
||||||
|
|
||||||
TimePreempt = (float)IBeatmapDifficultyInfo.DifficultyRange(difficulty.ApproachRate, PREEMPT_RANGE);
|
TimePreempt = IBeatmapDifficultyInfo.DifficultyRangeInt(difficulty.ApproachRate, PREEMPT_RANGE);
|
||||||
|
|
||||||
// Preempt time can go below 450ms. Normally, this is achieved via the DT mod which uniformly speeds up all animations game wide regardless of AR.
|
// Preempt time can go below 450ms. Normally, this is achieved via the DT mod which uniformly speeds up all animations game wide regardless of AR.
|
||||||
// This uniform speedup is hard to match 1:1, however we can at least make AR>10 (via mods) feel good by extending the upper linear function above.
|
// This uniform speedup is hard to match 1:1, however we can at least make AR>10 (via mods) feel good by extending the upper linear function above.
|
||||||
|
|||||||
@@ -175,7 +175,7 @@ namespace osu.Game.Rulesets.Osu
|
|||||||
new OsuModHardRock(),
|
new OsuModHardRock(),
|
||||||
new MultiMod(new OsuModSuddenDeath(), new OsuModPerfect()),
|
new MultiMod(new OsuModSuddenDeath(), new OsuModPerfect()),
|
||||||
new MultiMod(new OsuModDoubleTime(), new OsuModNightcore()),
|
new MultiMod(new OsuModDoubleTime(), new OsuModNightcore()),
|
||||||
new OsuModHidden(),
|
new MultiMod(new OsuModHidden(), new OsuModTraceable()),
|
||||||
new MultiMod(new OsuModFlashlight(), new OsuModBlinds()),
|
new MultiMod(new OsuModFlashlight(), new OsuModBlinds()),
|
||||||
new OsuModStrictTracking(),
|
new OsuModStrictTracking(),
|
||||||
new OsuModAccuracyChallenge(),
|
new OsuModAccuracyChallenge(),
|
||||||
@@ -209,7 +209,6 @@ namespace osu.Game.Rulesets.Osu
|
|||||||
new OsuModSpinIn(),
|
new OsuModSpinIn(),
|
||||||
new MultiMod(new OsuModGrow(), new OsuModDeflate()),
|
new MultiMod(new OsuModGrow(), new OsuModDeflate()),
|
||||||
new MultiMod(new ModWindUp(), new ModWindDown()),
|
new MultiMod(new ModWindUp(), new ModWindDown()),
|
||||||
new OsuModTraceable(),
|
|
||||||
new OsuModBarrelRoll(),
|
new OsuModBarrelRoll(),
|
||||||
new OsuModApproachDifferent(),
|
new OsuModApproachDifferent(),
|
||||||
new OsuModMuted(),
|
new OsuModMuted(),
|
||||||
@@ -230,6 +229,11 @@ namespace osu.Game.Rulesets.Osu
|
|||||||
new ModScoreV2(),
|
new ModScoreV2(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
case ModType.Special:
|
||||||
|
#if DEBUG
|
||||||
|
return Array.Empty<Mod>();
|
||||||
|
#endif
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return Array.Empty<Mod>();
|
return Array.Empty<Mod>();
|
||||||
}
|
}
|
||||||
@@ -249,7 +253,11 @@ namespace osu.Game.Rulesets.Osu
|
|||||||
|
|
||||||
public override string ShortName => SHORT_NAME;
|
public override string ShortName => SHORT_NAME;
|
||||||
|
|
||||||
|
#if !DEBUG
|
||||||
public override string PlayingVerb => "Clicking circles";
|
public override string PlayingVerb => "Clicking circles";
|
||||||
|
#else
|
||||||
|
public override string PlayingVerb => "Debugging circles";
|
||||||
|
#endif
|
||||||
|
|
||||||
public override RulesetSettingsSubsection CreateSettings() => new OsuSettingsSubsection(this);
|
public override RulesetSettingsSubsection CreateSettings() => new OsuSettingsSubsection(this);
|
||||||
|
|
||||||
@@ -278,19 +286,24 @@ namespace osu.Game.Rulesets.Osu
|
|||||||
|
|
||||||
public override IRulesetConfigManager CreateConfig(SettingsStore? settings) => new OsuRulesetConfigManager(settings, RulesetInfo);
|
public override IRulesetConfigManager CreateConfig(SettingsStore? settings) => new OsuRulesetConfigManager(settings, RulesetInfo);
|
||||||
|
|
||||||
protected override IEnumerable<HitResult> GetValidHitResults()
|
public override IEnumerable<HitResult> GetValidHitResults()
|
||||||
{
|
{
|
||||||
return new[]
|
return new[]
|
||||||
{
|
{
|
||||||
HitResult.Great,
|
HitResult.Great,
|
||||||
HitResult.Ok,
|
HitResult.Ok,
|
||||||
HitResult.Meh,
|
HitResult.Meh,
|
||||||
|
HitResult.Miss,
|
||||||
|
|
||||||
HitResult.LargeTickHit,
|
HitResult.LargeTickHit,
|
||||||
|
HitResult.LargeTickMiss,
|
||||||
HitResult.SmallTickHit,
|
HitResult.SmallTickHit,
|
||||||
|
HitResult.SmallTickMiss,
|
||||||
HitResult.SliderTailHit,
|
HitResult.SliderTailHit,
|
||||||
HitResult.SmallBonus,
|
HitResult.SmallBonus,
|
||||||
HitResult.LargeBonus,
|
HitResult.LargeBonus,
|
||||||
|
HitResult.IgnoreHit,
|
||||||
|
HitResult.IgnoreMiss,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -412,7 +425,8 @@ namespace osu.Game.Rulesets.Osu
|
|||||||
Description = "Affects how early objects appear on screen relative to their hit time.",
|
Description = "Affects how early objects appear on screen relative to their hit time.",
|
||||||
AdditionalMetrics =
|
AdditionalMetrics =
|
||||||
[
|
[
|
||||||
new RulesetBeatmapAttribute.AdditionalMetric("Approach time", LocalisableString.Interpolate($@"{IBeatmapDifficultyInfo.DifficultyRange(effectiveDifficulty.ApproachRate, OsuHitObject.PREEMPT_RANGE):#,0.##} ms"))
|
new RulesetBeatmapAttribute.AdditionalMetric("Approach time",
|
||||||
|
LocalisableString.Interpolate($@"{IBeatmapDifficultyInfo.DifficultyRangeInt(effectiveDifficulty.ApproachRate, OsuHitObject.PREEMPT_RANGE):#,0.##} ms"))
|
||||||
]
|
]
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -21,6 +21,8 @@ namespace osu.Game.Rulesets.Osu.Replays
|
|||||||
{
|
{
|
||||||
public class OsuAutoGenerator : OsuAutoGeneratorBase
|
public class OsuAutoGenerator : OsuAutoGeneratorBase
|
||||||
{
|
{
|
||||||
|
public const double MIN_FRAME_SEPARATION_FOR_ALTERNATING = 266;
|
||||||
|
|
||||||
public new OsuBeatmap Beatmap => (OsuBeatmap)base.Beatmap;
|
public new OsuBeatmap Beatmap => (OsuBeatmap)base.Beatmap;
|
||||||
|
|
||||||
#region Parameters
|
#region Parameters
|
||||||
@@ -245,7 +247,7 @@ namespace osu.Game.Rulesets.Osu.Replays
|
|||||||
double timeDifference = ApplyModsToTimeDelta(lastFrame.Time, h.StartTime);
|
double timeDifference = ApplyModsToTimeDelta(lastFrame.Time, h.StartTime);
|
||||||
OsuReplayFrame? lastLastFrame = Frames.Count >= 2 ? (OsuReplayFrame)Frames[^2] : null;
|
OsuReplayFrame? lastLastFrame = Frames.Count >= 2 ? (OsuReplayFrame)Frames[^2] : null;
|
||||||
|
|
||||||
if (timeDifference > 0)
|
if (timeDifference >= 0)
|
||||||
{
|
{
|
||||||
// If the last frame is a key-up frame and there has been no wait period, adjust the last frame's position such that it begins eased movement instantaneously.
|
// If the last frame is a key-up frame and there has been no wait period, adjust the last frame's position such that it begins eased movement instantaneously.
|
||||||
if (lastLastFrame != null && lastFrame is OsuKeyUpReplayFrame && !hasWaited)
|
if (lastLastFrame != null && lastFrame is OsuKeyUpReplayFrame && !hasWaited)
|
||||||
@@ -266,7 +268,7 @@ namespace osu.Game.Rulesets.Osu.Replays
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Start alternating once the time separation is too small (faster than ~225BPM).
|
// Start alternating once the time separation is too small (faster than ~225BPM).
|
||||||
if (timeDifference > 0 && timeDifference < 266)
|
if (timeDifference >= 0 && timeDifference < MIN_FRAME_SEPARATION_FOR_ALTERNATING)
|
||||||
buttonIndex++;
|
buttonIndex++;
|
||||||
else
|
else
|
||||||
buttonIndex = 0;
|
buttonIndex = 0;
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
protected bool AllowPartRotation { get; set; }
|
protected bool AllowPartRotation { get; set; }
|
||||||
|
|
||||||
private Vector2 cursorScale;
|
private Vector2 cursorScale = Vector2.One;
|
||||||
|
|
||||||
public Vector2 CursorScale
|
public Vector2 CursorScale
|
||||||
{
|
{
|
||||||
@@ -198,7 +198,7 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor
|
|||||||
float distance = diff.Length;
|
float distance = diff.Length;
|
||||||
Vector2 direction = diff / distance;
|
Vector2 direction = diff / distance;
|
||||||
|
|
||||||
float interval = Texture.DisplayWidth / 2.5f * IntervalMultiplier;
|
float interval = Texture.DisplayWidth * CursorScale.X / 2.5f * IntervalMultiplier;
|
||||||
float stopAt = distance - (AvoidDrawingNearCursor ? interval : 0);
|
float stopAt = distance - (AvoidDrawingNearCursor ? interval : 0);
|
||||||
|
|
||||||
for (float d = interval; d < stopAt; d += interval)
|
for (float d = interval; d < stopAt; d += interval)
|
||||||
|
|||||||
@@ -3,7 +3,9 @@
|
|||||||
|
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Framework.Graphics.UserInterface;
|
||||||
using osu.Framework.Localisation;
|
using osu.Framework.Localisation;
|
||||||
|
using osu.Game.Graphics.UserInterfaceV2;
|
||||||
using osu.Game.Localisation;
|
using osu.Game.Localisation;
|
||||||
using osu.Game.Overlays.Settings;
|
using osu.Game.Overlays.Settings;
|
||||||
using osu.Game.Rulesets.Osu.Configuration;
|
using osu.Game.Rulesets.Osu.Configuration;
|
||||||
@@ -27,32 +29,34 @@ namespace osu.Game.Rulesets.Osu.UI
|
|||||||
|
|
||||||
Children = new Drawable[]
|
Children = new Drawable[]
|
||||||
{
|
{
|
||||||
new SettingsCheckbox
|
new SettingsItemV2(new FormCheckBox
|
||||||
{
|
{
|
||||||
LabelText = RulesetSettingsStrings.SnakingInSliders,
|
Caption = RulesetSettingsStrings.SnakingInSliders,
|
||||||
Current = config.GetBindable<bool>(OsuRulesetSetting.SnakingInSliders)
|
Current = config.GetBindable<bool>(OsuRulesetSetting.SnakingInSliders)
|
||||||
},
|
}),
|
||||||
new SettingsCheckbox
|
new SettingsItemV2(new FormCheckBox
|
||||||
{
|
{
|
||||||
ClassicDefault = false,
|
Caption = RulesetSettingsStrings.SnakingOutSliders,
|
||||||
LabelText = RulesetSettingsStrings.SnakingOutSliders,
|
|
||||||
Current = config.GetBindable<bool>(OsuRulesetSetting.SnakingOutSliders)
|
Current = config.GetBindable<bool>(OsuRulesetSetting.SnakingOutSliders)
|
||||||
},
|
})
|
||||||
new SettingsCheckbox
|
|
||||||
{
|
{
|
||||||
LabelText = RulesetSettingsStrings.CursorTrail,
|
ApplyClassicDefault = c => ((IHasCurrentValue<bool>)c).Current.Value = false,
|
||||||
|
},
|
||||||
|
new SettingsItemV2(new FormCheckBox
|
||||||
|
{
|
||||||
|
Caption = RulesetSettingsStrings.CursorTrail,
|
||||||
Current = config.GetBindable<bool>(OsuRulesetSetting.ShowCursorTrail)
|
Current = config.GetBindable<bool>(OsuRulesetSetting.ShowCursorTrail)
|
||||||
},
|
}),
|
||||||
new SettingsCheckbox
|
new SettingsItemV2(new FormCheckBox
|
||||||
{
|
{
|
||||||
LabelText = RulesetSettingsStrings.CursorRipples,
|
Caption = RulesetSettingsStrings.CursorRipples,
|
||||||
Current = config.GetBindable<bool>(OsuRulesetSetting.ShowCursorRipples)
|
Current = config.GetBindable<bool>(OsuRulesetSetting.ShowCursorRipples)
|
||||||
},
|
}),
|
||||||
new SettingsEnumDropdown<PlayfieldBorderStyle>
|
new SettingsItemV2(new FormEnumDropdown<PlayfieldBorderStyle>
|
||||||
{
|
{
|
||||||
LabelText = RulesetSettingsStrings.PlayfieldBorderStyle,
|
Caption = RulesetSettingsStrings.PlayfieldBorderStyle,
|
||||||
Current = config.GetBindable<PlayfieldBorderStyle>(OsuRulesetSetting.PlayfieldBorderStyle),
|
Current = config.GetBindable<PlayfieldBorderStyle>(OsuRulesetSetting.PlayfieldBorderStyle),
|
||||||
},
|
}),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
<PropertyGroup Label="Nuget">
|
<PropertyGroup Label="Nuget">
|
||||||
<Title>osu! (ruleset)</Title>
|
<Title>osu! (ruleset)</Title>
|
||||||
<PackageId>ppy.osu.Game.Rulesets.Osu</PackageId>
|
<PackageId>jvnkosu.Client.Rulesets.Osu</PackageId>
|
||||||
<IsPackable>true</IsPackable>
|
<IsPackable>true</IsPackable>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
|
|||||||
@@ -35,11 +35,9 @@
|
|||||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||||
</array>
|
</array>
|
||||||
<key>XSAppIconAssets</key>
|
|
||||||
<string>Assets.xcassets/AppIcon.appiconset</string>
|
|
||||||
<key>UIApplicationSupportsIndirectInputEvents</key>
|
<key>UIApplicationSupportsIndirectInputEvents</key>
|
||||||
<true/>
|
<true/>
|
||||||
<key>CADisableMinimumFrameDurationOnPhone</key>
|
<key>CADisableMinimumFrameDurationOnPhone</key>
|
||||||
<true/>
|
<true/>
|
||||||
</dict>
|
</dict>
|
||||||
</plist>
|
</plist>
|
||||||
|
|||||||
@@ -222,15 +222,18 @@ namespace osu.Game.Rulesets.Taiko
|
|||||||
|
|
||||||
public override RulesetSettingsSubsection CreateSettings() => new TaikoSettingsSubsection(this);
|
public override RulesetSettingsSubsection CreateSettings() => new TaikoSettingsSubsection(this);
|
||||||
|
|
||||||
protected override IEnumerable<HitResult> GetValidHitResults()
|
public override IEnumerable<HitResult> GetValidHitResults()
|
||||||
{
|
{
|
||||||
return new[]
|
return new[]
|
||||||
{
|
{
|
||||||
HitResult.Great,
|
HitResult.Great,
|
||||||
HitResult.Ok,
|
HitResult.Ok,
|
||||||
|
HitResult.Miss,
|
||||||
|
|
||||||
HitResult.SmallBonus,
|
HitResult.SmallBonus,
|
||||||
HitResult.LargeBonus,
|
HitResult.LargeBonus,
|
||||||
|
HitResult.IgnoreHit,
|
||||||
|
HitResult.IgnoreMiss,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Localisation;
|
using osu.Framework.Localisation;
|
||||||
|
using osu.Game.Graphics.UserInterfaceV2;
|
||||||
using osu.Game.Localisation;
|
using osu.Game.Localisation;
|
||||||
using osu.Game.Overlays.Settings;
|
using osu.Game.Overlays.Settings;
|
||||||
using osu.Game.Rulesets.Taiko.Configuration;
|
using osu.Game.Rulesets.Taiko.Configuration;
|
||||||
@@ -26,11 +27,11 @@ namespace osu.Game.Rulesets.Taiko
|
|||||||
|
|
||||||
Children = new Drawable[]
|
Children = new Drawable[]
|
||||||
{
|
{
|
||||||
new SettingsEnumDropdown<TaikoTouchControlScheme>
|
new SettingsItemV2(new FormEnumDropdown<TaikoTouchControlScheme>
|
||||||
{
|
{
|
||||||
LabelText = RulesetSettingsStrings.TouchControlScheme,
|
Caption = RulesetSettingsStrings.TouchControlScheme,
|
||||||
Current = config.GetBindable<TaikoTouchControlScheme>(TaikoRulesetSetting.TouchControlScheme)
|
Current = config.GetBindable<TaikoTouchControlScheme>(TaikoRulesetSetting.TouchControlScheme)
|
||||||
}
|
})
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -194,7 +194,7 @@ namespace osu.Game.Rulesets.Taiko.UI
|
|||||||
|
|
||||||
var hitWindows = new TaikoHitWindows();
|
var hitWindows = new TaikoHitWindows();
|
||||||
|
|
||||||
HitResult[] usableHitResults = Enum.GetValues<HitResult>().Where(r => hitWindows.IsHitResultAllowed(r)).ToArray();
|
HitResult[] usableHitResults = Enum.GetValues<HitResult>().Where(hitWindows.IsHitResultAllowed).ToArray();
|
||||||
|
|
||||||
AddInternal(judgementPooler = new JudgementPooler<DrawableTaikoJudgement>(usableHitResults));
|
AddInternal(judgementPooler = new JudgementPooler<DrawableTaikoJudgement>(usableHitResults));
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
<PropertyGroup Label="Nuget">
|
<PropertyGroup Label="Nuget">
|
||||||
<Title>osu!taiko (ruleset)</Title>
|
<Title>osu!taiko (ruleset)</Title>
|
||||||
<PackageId>ppy.osu.Game.Rulesets.Taiko</PackageId>
|
<PackageId>jvnkosu.Client.Rulesets.Taiko</PackageId>
|
||||||
<IsPackable>true</IsPackable>
|
<IsPackable>true</IsPackable>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
|
|||||||
@@ -35,8 +35,31 @@
|
|||||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||||
</array>
|
</array>
|
||||||
<key>XSAppIconAssets</key>
|
<key>CFBundleIcons~ipad</key>
|
||||||
<string>Assets.xcassets/AppIcon.appiconset</string>
|
<dict>
|
||||||
|
<key>CFBundlePrimaryIcon</key>
|
||||||
|
<dict>
|
||||||
|
<key>CFBundleIconFiles</key>
|
||||||
|
<array>
|
||||||
|
<string>AppIcon60x60</string>
|
||||||
|
</array>
|
||||||
|
<key>CFBundleIconName</key>
|
||||||
|
<string>AppIcon</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
<key>CFBundleIcons</key>
|
||||||
|
<dict>
|
||||||
|
<key>CFBundlePrimaryIcon</key>
|
||||||
|
<dict>
|
||||||
|
<key>CFBundleIconFiles</key>
|
||||||
|
<array>
|
||||||
|
<string>AppIcon60x60</string>
|
||||||
|
<string>AppIcon76x76</string>
|
||||||
|
</array>
|
||||||
|
<key>CFBundleIconName</key>
|
||||||
|
<string>AppIcon</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
<key>UIApplicationSupportsIndirectInputEvents</key>
|
<key>UIApplicationSupportsIndirectInputEvents</key>
|
||||||
<true/>
|
<true/>
|
||||||
<key>CADisableMinimumFrameDurationOnPhone</key>
|
<key>CADisableMinimumFrameDurationOnPhone</key>
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
#nullable disable
|
#nullable disable
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
@@ -15,6 +16,7 @@ using osu.Framework.Testing;
|
|||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Rulesets;
|
using osu.Game.Rulesets;
|
||||||
using osu.Game.Rulesets.Mods;
|
using osu.Game.Rulesets.Mods;
|
||||||
|
using osu.Game.Rulesets.Objects;
|
||||||
using osu.Game.Rulesets.Osu.Mods;
|
using osu.Game.Rulesets.Osu.Mods;
|
||||||
using osu.Game.Tests.Beatmaps.IO;
|
using osu.Game.Tests.Beatmaps.IO;
|
||||||
using osu.Game.Tests.Visual;
|
using osu.Game.Tests.Visual;
|
||||||
@@ -34,6 +36,12 @@ namespace osu.Game.Tests.Beatmaps
|
|||||||
|
|
||||||
private IBindable<StarDifficulty> starDifficultyBindable;
|
private IBindable<StarDifficulty> starDifficultyBindable;
|
||||||
|
|
||||||
|
[Resolved]
|
||||||
|
private BeatmapManager beatmapManager { get; set; }
|
||||||
|
|
||||||
|
[Resolved]
|
||||||
|
private BeatmapDifficultyCache actualDifficultyCache { get; set; }
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load(OsuGameBase osu)
|
private void load(OsuGameBase osu)
|
||||||
{
|
{
|
||||||
@@ -55,6 +63,36 @@ namespace osu.Game.Tests.Beatmaps
|
|||||||
AddUntilStep($"star difficulty -> {BASE_STARS}", () => starDifficultyBindable.Value.Stars == BASE_STARS);
|
AddUntilStep($"star difficulty -> {BASE_STARS}", () => starDifficultyBindable.Value.Stars == BASE_STARS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestInvalidationFlow()
|
||||||
|
{
|
||||||
|
BeatmapInfo postEditBeatmapInfo = null;
|
||||||
|
BeatmapInfo preEditBeatmapInfo = null;
|
||||||
|
|
||||||
|
IBindable<StarDifficulty> bindableDifficulty = null;
|
||||||
|
|
||||||
|
AddStep("get bindable stars", () =>
|
||||||
|
{
|
||||||
|
preEditBeatmapInfo = importedSet.Beatmaps.First();
|
||||||
|
bindableDifficulty = actualDifficultyCache.GetBindableDifficulty(preEditBeatmapInfo);
|
||||||
|
});
|
||||||
|
|
||||||
|
AddUntilStep("wait for stars retrieved", () => bindableDifficulty.Value.Stars, () => Is.GreaterThan(0));
|
||||||
|
|
||||||
|
AddStep("remove all hitobjects", () =>
|
||||||
|
{
|
||||||
|
var working = beatmapManager.GetWorkingBeatmap(preEditBeatmapInfo);
|
||||||
|
|
||||||
|
((IList<HitObject>)working.Beatmap.HitObjects).Clear();
|
||||||
|
|
||||||
|
beatmapManager.Save(working.BeatmapInfo, working.Beatmap);
|
||||||
|
postEditBeatmapInfo = working.BeatmapInfo;
|
||||||
|
});
|
||||||
|
|
||||||
|
AddAssert("stars is now zero", () => actualDifficultyCache.GetDifficultyAsync(postEditBeatmapInfo).GetResultSafely()!.Value.Stars, () => Is.Zero);
|
||||||
|
AddUntilStep("bindable stars is now zero", () => bindableDifficulty.Value.Stars, () => Is.Zero);
|
||||||
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void TestStarDifficultyChangesOnModSettings()
|
public void TestStarDifficultyChangesOnModSettings()
|
||||||
{
|
{
|
||||||
@@ -76,6 +114,30 @@ namespace osu.Game.Tests.Beatmaps
|
|||||||
AddUntilStep($"star difficulty -> {BASE_STARS + 1.75}", () => starDifficultyBindable.Value.Stars == BASE_STARS + 1.75);
|
AddUntilStep($"star difficulty -> {BASE_STARS + 1.75}", () => starDifficultyBindable.Value.Stars == BASE_STARS + 1.75);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestStarDifficultyChangesOnModSettingsCorrectlyTrackAcrossReferenceChanges()
|
||||||
|
{
|
||||||
|
OsuModDoubleTime dt = null;
|
||||||
|
|
||||||
|
AddStep("set computation function", () => difficultyCache.ComputeDifficulty = lookup =>
|
||||||
|
{
|
||||||
|
var modRateAdjust = (ModRateAdjust)lookup.OrderedMods.SingleOrDefault(mod => mod is ModRateAdjust);
|
||||||
|
return new StarDifficulty(BASE_STARS + modRateAdjust?.SpeedChange.Value ?? 0, 0);
|
||||||
|
});
|
||||||
|
|
||||||
|
AddStep("change selected mod to DT", () => SelectedMods.Value = new[] { dt = new OsuModDoubleTime { SpeedChange = { Value = 1.5 } } });
|
||||||
|
AddUntilStep($"star difficulty -> {BASE_STARS + 1.5}", () => starDifficultyBindable.Value.Stars == BASE_STARS + 1.5);
|
||||||
|
|
||||||
|
AddStep("change DT speed to 1.25", () => dt.SpeedChange.Value = 1.25);
|
||||||
|
AddUntilStep($"star difficulty -> {BASE_STARS + 1.25}", () => starDifficultyBindable.Value.Stars == BASE_STARS + 1.25);
|
||||||
|
|
||||||
|
AddStep("reconstruct DT mod with same settings", () => SelectedMods.Value = new[] { dt = (OsuModDoubleTime)dt.DeepClone() });
|
||||||
|
AddUntilStep($"star difficulty -> {BASE_STARS + 1.25}", () => starDifficultyBindable.Value.Stars == BASE_STARS + 1.25);
|
||||||
|
|
||||||
|
AddStep("change DT speed to 1.25", () => dt.SpeedChange.Value = 2);
|
||||||
|
AddUntilStep($"star difficulty -> {BASE_STARS + 2}", () => starDifficultyBindable.Value.Stars == BASE_STARS + 2);
|
||||||
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void TestStarDifficultyAdjustHashCodeConflict()
|
public void TestStarDifficultyAdjustHashCodeConflict()
|
||||||
{
|
{
|
||||||
@@ -122,8 +184,10 @@ namespace osu.Game.Tests.Beatmaps
|
|||||||
[Test]
|
[Test]
|
||||||
public void TestKeyDoesntEqualWithDifferentModSettings()
|
public void TestKeyDoesntEqualWithDifferentModSettings()
|
||||||
{
|
{
|
||||||
var key1 = new BeatmapDifficultyCache.DifficultyCacheLookup(new BeatmapInfo { ID = guid }, new RulesetInfo { OnlineID = 0 }, new Mod[] { new OsuModDoubleTime { SpeedChange = { Value = 1.1 } } });
|
var key1 = new BeatmapDifficultyCache.DifficultyCacheLookup(new BeatmapInfo { ID = guid }, new RulesetInfo { OnlineID = 0 },
|
||||||
var key2 = new BeatmapDifficultyCache.DifficultyCacheLookup(new BeatmapInfo { ID = guid }, new RulesetInfo { OnlineID = 0 }, new Mod[] { new OsuModDoubleTime { SpeedChange = { Value = 1.9 } } });
|
new Mod[] { new OsuModDoubleTime { SpeedChange = { Value = 1.1 } } });
|
||||||
|
var key2 = new BeatmapDifficultyCache.DifficultyCacheLookup(new BeatmapInfo { ID = guid }, new RulesetInfo { OnlineID = 0 },
|
||||||
|
new Mod[] { new OsuModDoubleTime { SpeedChange = { Value = 1.9 } } });
|
||||||
|
|
||||||
Assert.That(key1, Is.Not.EqualTo(key2));
|
Assert.That(key1, Is.Not.EqualTo(key2));
|
||||||
Assert.That(key1.GetHashCode(), Is.Not.EqualTo(key2.GetHashCode()));
|
Assert.That(key1.GetHashCode(), Is.Not.EqualTo(key2.GetHashCode()));
|
||||||
@@ -132,8 +196,10 @@ namespace osu.Game.Tests.Beatmaps
|
|||||||
[Test]
|
[Test]
|
||||||
public void TestKeyEqualWithMatchingModSettings()
|
public void TestKeyEqualWithMatchingModSettings()
|
||||||
{
|
{
|
||||||
var key1 = new BeatmapDifficultyCache.DifficultyCacheLookup(new BeatmapInfo { ID = guid }, new RulesetInfo { OnlineID = 0 }, new Mod[] { new OsuModDoubleTime { SpeedChange = { Value = 1.25 } } });
|
var key1 = new BeatmapDifficultyCache.DifficultyCacheLookup(new BeatmapInfo { ID = guid }, new RulesetInfo { OnlineID = 0 },
|
||||||
var key2 = new BeatmapDifficultyCache.DifficultyCacheLookup(new BeatmapInfo { ID = guid }, new RulesetInfo { OnlineID = 0 }, new Mod[] { new OsuModDoubleTime { SpeedChange = { Value = 1.25 } } });
|
new Mod[] { new OsuModDoubleTime { SpeedChange = { Value = 1.25 } } });
|
||||||
|
var key2 = new BeatmapDifficultyCache.DifficultyCacheLookup(new BeatmapInfo { ID = guid }, new RulesetInfo { OnlineID = 0 },
|
||||||
|
new Mod[] { new OsuModDoubleTime { SpeedChange = { Value = 1.25 } } });
|
||||||
|
|
||||||
Assert.That(key1, Is.EqualTo(key2));
|
Assert.That(key1, Is.EqualTo(key2));
|
||||||
Assert.That(key1.GetHashCode(), Is.EqualTo(key2.GetHashCode()));
|
Assert.That(key1.GetHashCode(), Is.EqualTo(key2.GetHashCode()));
|
||||||
|
|||||||
@@ -247,7 +247,7 @@ namespace osu.Game.Tests.Beatmaps
|
|||||||
|
|
||||||
AddStep("change all start times", () =>
|
AddStep("change all start times", () =>
|
||||||
{
|
{
|
||||||
editorBeatmap.HitObjectUpdated += h => updatedObjects.Add(h);
|
editorBeatmap.HitObjectUpdated += updatedObjects.Add;
|
||||||
|
|
||||||
for (int i = 0; i < 10; i++)
|
for (int i = 0; i < 10; i++)
|
||||||
allHitObjects[i].StartTime += 10;
|
allHitObjects[i].StartTime += 10;
|
||||||
@@ -282,7 +282,7 @@ namespace osu.Game.Tests.Beatmaps
|
|||||||
|
|
||||||
AddStep("change start time twice", () =>
|
AddStep("change start time twice", () =>
|
||||||
{
|
{
|
||||||
editorBeatmap.HitObjectUpdated += h => updatedObjects.Add(h);
|
editorBeatmap.HitObjectUpdated += updatedObjects.Add;
|
||||||
|
|
||||||
editorBeatmap.HitObjects[0].StartTime = 10;
|
editorBeatmap.HitObjects[0].StartTime = 10;
|
||||||
editorBeatmap.HitObjects[0].StartTime = 20;
|
editorBeatmap.HitObjects[0].StartTime = 20;
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ namespace osu.Game.Tests.Chat
|
|||||||
public void OneTimeSetUp()
|
public void OneTimeSetUp()
|
||||||
{
|
{
|
||||||
originalWebsiteRootUrl = MessageFormatter.WebsiteRootUrl;
|
originalWebsiteRootUrl = MessageFormatter.WebsiteRootUrl;
|
||||||
MessageFormatter.WebsiteRootUrl = "dev.ppy.sh";
|
MessageFormatter.WebsiteRootUrl = "osu.jvnko.boats";
|
||||||
}
|
}
|
||||||
|
|
||||||
[OneTimeTearDown]
|
[OneTimeTearDown]
|
||||||
@@ -47,11 +47,11 @@ namespace osu.Game.Tests.Chat
|
|||||||
[Test]
|
[Test]
|
||||||
public void TestSupportedProtocolLinkParsing()
|
public void TestSupportedProtocolLinkParsing()
|
||||||
{
|
{
|
||||||
Message result = MessageFormatter.FormatMessage(new Message { Content = "forgotspacehttps://dev.ppy.sh joinmyosump://12345 jointheosu://chan/#english" });
|
Message result = MessageFormatter.FormatMessage(new Message { Content = "forgotspacehttps://osu.jvnko.boats joinmyjvnkosump://12345 jointhejvnkosu://chan/#english" });
|
||||||
|
|
||||||
Assert.AreEqual("https://dev.ppy.sh", result.Links[0].Url);
|
Assert.AreEqual("https://osu.jvnko.boats", result.Links[0].Url);
|
||||||
Assert.AreEqual("osump://12345", result.Links[1].Url);
|
Assert.AreEqual("jvnkosump://12345", result.Links[1].Url);
|
||||||
Assert.AreEqual("osu://chan/#english", result.Links[2].Url);
|
Assert.AreEqual("jvnkosu://chan/#english", result.Links[2].Url);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
@@ -66,15 +66,15 @@ namespace osu.Game.Tests.Chat
|
|||||||
Assert.AreEqual(36, result.Links[0].Length);
|
Assert.AreEqual(36, result.Links[0].Length);
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestCase(LinkAction.OpenBeatmap, "456", "https://dev.ppy.sh/beatmapsets/123#osu/456")]
|
[TestCase(LinkAction.OpenBeatmap, "456", "https://osu.jvnko.boats/beatmapsets/123#osu/456")]
|
||||||
[TestCase(LinkAction.OpenBeatmap, "456", "https://dev.ppy.sh/beatmapsets/123#osu/456?whatever")]
|
[TestCase(LinkAction.OpenBeatmap, "456", "https://osu.jvnko.boats/beatmapsets/123#osu/456?whatever")]
|
||||||
[TestCase(LinkAction.OpenBeatmap, "456", "https://dev.ppy.sh/beatmapsets/123/456")]
|
[TestCase(LinkAction.OpenBeatmap, "456", "https://osu.jvnko.boats/beatmapsets/123/456")]
|
||||||
[TestCase(LinkAction.External, "https://dev.ppy.sh/beatmapsets/abc/def", "https://dev.ppy.sh/beatmapsets/abc/def")]
|
[TestCase(LinkAction.External, "https://osu.jvnko.boats/beatmapsets/abc/def", "https://osu.jvnko.boats/beatmapsets/abc/def")]
|
||||||
[TestCase(LinkAction.OpenBeatmapSet, "123", "https://dev.ppy.sh/beatmapsets/123")]
|
[TestCase(LinkAction.OpenBeatmapSet, "123", "https://osu.jvnko.boats/beatmapsets/123")]
|
||||||
[TestCase(LinkAction.OpenBeatmapSet, "123", "https://dev.ppy.sh/beatmapsets/123/whatever")]
|
[TestCase(LinkAction.OpenBeatmapSet, "123", "https://osu.jvnko.boats/beatmapsets/123/whatever")]
|
||||||
[TestCase(LinkAction.External, "https://dev.ppy.sh/beatmapsets/abc", "https://dev.ppy.sh/beatmapsets/abc")]
|
[TestCase(LinkAction.External, "https://osu.jvnko.boats/beatmapsets/abc", "https://osu.jvnko.boats/beatmapsets/abc")]
|
||||||
[TestCase(LinkAction.External, "https://dev.ppy.sh/beatmapsets/discussions", "https://dev.ppy.sh/beatmapsets/discussions")]
|
[TestCase(LinkAction.External, "https://osu.jvnko.boats/beatmapsets/discussions", "https://osu.jvnko.boats/beatmapsets/discussions")]
|
||||||
[TestCase(LinkAction.External, "https://dev.ppy.sh/beatmapsets/discussions/123", "https://dev.ppy.sh/beatmapsets/discussions/123")]
|
[TestCase(LinkAction.External, "https://osu.jvnko.boats/beatmapsets/discussions/123", "https://osu.jvnko.boats/beatmapsets/discussions/123")]
|
||||||
public void TestBeatmapLinks(LinkAction expectedAction, string expectedArg, string link)
|
public void TestBeatmapLinks(LinkAction expectedAction, string expectedArg, string link)
|
||||||
{
|
{
|
||||||
Message result = MessageFormatter.FormatMessage(new Message { Content = link });
|
Message result = MessageFormatter.FormatMessage(new Message { Content = link });
|
||||||
@@ -150,7 +150,7 @@ namespace osu.Game.Tests.Chat
|
|||||||
|
|
||||||
Assert.AreEqual("This is a Wiki Link.", result.DisplayContent);
|
Assert.AreEqual("This is a Wiki Link.", result.DisplayContent);
|
||||||
Assert.AreEqual(1, result.Links.Count);
|
Assert.AreEqual(1, result.Links.Count);
|
||||||
Assert.AreEqual("https://dev.ppy.sh/wiki/Wiki Link", result.Links[0].Url);
|
Assert.AreEqual("https://osu.jvnko.boats/wiki/Wiki Link", result.Links[0].Url);
|
||||||
Assert.AreEqual(10, result.Links[0].Index);
|
Assert.AreEqual(10, result.Links[0].Index);
|
||||||
Assert.AreEqual(9, result.Links[0].Length);
|
Assert.AreEqual(9, result.Links[0].Length);
|
||||||
}
|
}
|
||||||
@@ -163,15 +163,15 @@ namespace osu.Game.Tests.Chat
|
|||||||
Assert.AreEqual("This is a Wiki Link Wiki:LinkWiki.Link.", result.DisplayContent);
|
Assert.AreEqual("This is a Wiki Link Wiki:LinkWiki.Link.", result.DisplayContent);
|
||||||
Assert.AreEqual(3, result.Links.Count);
|
Assert.AreEqual(3, result.Links.Count);
|
||||||
|
|
||||||
Assert.AreEqual("https://dev.ppy.sh/wiki/Wiki Link", result.Links[0].Url);
|
Assert.AreEqual("https://osu.jvnko.boats/wiki/Wiki Link", result.Links[0].Url);
|
||||||
Assert.AreEqual(10, result.Links[0].Index);
|
Assert.AreEqual(10, result.Links[0].Index);
|
||||||
Assert.AreEqual(9, result.Links[0].Length);
|
Assert.AreEqual(9, result.Links[0].Length);
|
||||||
|
|
||||||
Assert.AreEqual("https://dev.ppy.sh/wiki/Wiki:Link", result.Links[1].Url);
|
Assert.AreEqual("https://osu.jvnko.boats/wiki/Wiki:Link", result.Links[1].Url);
|
||||||
Assert.AreEqual(20, result.Links[1].Index);
|
Assert.AreEqual(20, result.Links[1].Index);
|
||||||
Assert.AreEqual(9, result.Links[1].Length);
|
Assert.AreEqual(9, result.Links[1].Length);
|
||||||
|
|
||||||
Assert.AreEqual("https://dev.ppy.sh/wiki/Wiki.Link", result.Links[2].Url);
|
Assert.AreEqual("https://osu.jvnko.boats/wiki/Wiki.Link", result.Links[2].Url);
|
||||||
Assert.AreEqual(29, result.Links[2].Index);
|
Assert.AreEqual(29, result.Links[2].Index);
|
||||||
Assert.AreEqual(9, result.Links[2].Length);
|
Assert.AreEqual(9, result.Links[2].Length);
|
||||||
}
|
}
|
||||||
@@ -452,7 +452,7 @@ namespace osu.Game.Tests.Chat
|
|||||||
Assert.AreEqual(1, result.Links.Count);
|
Assert.AreEqual(1, result.Links.Count);
|
||||||
Assert.AreEqual($"{OsuGameBase.OSU_PROTOCOL}chan/#english", result.Links[0].Url);
|
Assert.AreEqual($"{OsuGameBase.OSU_PROTOCOL}chan/#english", result.Links[0].Url);
|
||||||
Assert.AreEqual(26, result.Links[0].Index);
|
Assert.AreEqual(26, result.Links[0].Index);
|
||||||
Assert.AreEqual(19, result.Links[0].Length);
|
Assert.AreEqual(23, result.Links[0].Length);
|
||||||
|
|
||||||
result = MessageFormatter.FormatMessage(new Message { Content = $"This is a [custom protocol]({OsuGameBase.OSU_PROTOCOL}chan/#english)." });
|
result = MessageFormatter.FormatMessage(new Message { Content = $"This is a [custom protocol]({OsuGameBase.OSU_PROTOCOL}chan/#english)." });
|
||||||
|
|
||||||
@@ -467,13 +467,13 @@ namespace osu.Game.Tests.Chat
|
|||||||
[Test]
|
[Test]
|
||||||
public void TestOsuMpProtocol()
|
public void TestOsuMpProtocol()
|
||||||
{
|
{
|
||||||
Message result = MessageFormatter.FormatMessage(new Message { Content = "Join my multiplayer game osump://12346." });
|
Message result = MessageFormatter.FormatMessage(new Message { Content = "Join my multiplayer game jvnkosump://12346." });
|
||||||
|
|
||||||
Assert.AreEqual(result.Content, result.DisplayContent);
|
Assert.AreEqual(result.Content, result.DisplayContent);
|
||||||
Assert.AreEqual(1, result.Links.Count);
|
Assert.AreEqual(1, result.Links.Count);
|
||||||
Assert.AreEqual("osump://12346", result.Links[0].Url);
|
Assert.AreEqual("jvnkosump://12346", result.Links[0].Url);
|
||||||
Assert.AreEqual(25, result.Links[0].Index);
|
Assert.AreEqual(25, result.Links[0].Index);
|
||||||
Assert.AreEqual(13, result.Links[0].Length);
|
Assert.AreEqual(17, result.Links[0].Length);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
@@ -499,7 +499,7 @@ namespace osu.Game.Tests.Chat
|
|||||||
Assert.AreEqual("This is a simple test with some [traps] and wiki links. Don't forget to visit https://osu.ppy.sh now![emoji]", result.DisplayContent);
|
Assert.AreEqual("This is a simple test with some [traps] and wiki links. Don't forget to visit https://osu.ppy.sh now![emoji]", result.DisplayContent);
|
||||||
Assert.AreEqual(4, result.Links.Count);
|
Assert.AreEqual(4, result.Links.Count);
|
||||||
|
|
||||||
Link f = result.Links.Find(l => l.Url == "https://dev.ppy.sh/wiki/wiki links");
|
Link f = result.Links.Find(l => l.Url == "https://osu.jvnko.boats/wiki/wiki links");
|
||||||
Assert.That(f, Is.Not.Null);
|
Assert.That(f, Is.Not.Null);
|
||||||
Assert.AreEqual(44, f.Index);
|
Assert.AreEqual(44, f.Index);
|
||||||
Assert.AreEqual(10, f.Length);
|
Assert.AreEqual(10, f.Length);
|
||||||
@@ -554,8 +554,8 @@ namespace osu.Game.Tests.Chat
|
|||||||
Assert.AreEqual("/relative", result.Argument);
|
Assert.AreEqual("/relative", result.Argument);
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestCase("https://dev.ppy.sh/home/changelog", "")]
|
[TestCase("https://osu.jvnko.boats/home/changelog", "")]
|
||||||
[TestCase("https://dev.ppy.sh/home/changelog/lazer/2021.1012", "lazer/2021.1012")]
|
[TestCase("https://osu.jvnko.boats/home/changelog/lazer/2021.1012", "lazer/2021.1012")]
|
||||||
public void TestChangelogLinks(string link, string expectedArg)
|
public void TestChangelogLinks(string link, string expectedArg)
|
||||||
{
|
{
|
||||||
LinkDetails result = MessageFormatter.GetLinkDetails(link);
|
LinkDetails result = MessageFormatter.GetLinkDetails(link);
|
||||||
|
|||||||
@@ -104,10 +104,7 @@ namespace osu.Game.Tests.Database
|
|||||||
Assert.AreNotEqual(detachedBeatmapSet.Status, BeatmapOnlineStatus.Ranked);
|
Assert.AreNotEqual(detachedBeatmapSet.Status, BeatmapOnlineStatus.Ranked);
|
||||||
detachedBeatmapSet.Status = BeatmapOnlineStatus.Ranked;
|
detachedBeatmapSet.Status = BeatmapOnlineStatus.Ranked;
|
||||||
|
|
||||||
beatmapSet.PerformWrite(s =>
|
beatmapSet.PerformWrite(detachedBeatmapSet.CopyChangesToRealm);
|
||||||
{
|
|
||||||
detachedBeatmapSet.CopyChangesToRealm(s);
|
|
||||||
});
|
|
||||||
|
|
||||||
beatmapSet.PerformRead(s =>
|
beatmapSet.PerformRead(s =>
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ using System.Linq;
|
|||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Rulesets;
|
using osu.Game.Rulesets;
|
||||||
|
using osu.Game.Rulesets.Catch;
|
||||||
using osu.Game.Rulesets.Difficulty;
|
using osu.Game.Rulesets.Difficulty;
|
||||||
using osu.Game.Rulesets.Mods;
|
using osu.Game.Rulesets.Mods;
|
||||||
using osu.Game.Rulesets.Osu;
|
using osu.Game.Rulesets.Osu;
|
||||||
@@ -116,6 +117,69 @@ namespace osu.Game.Tests.Database
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestFakedRulesetIdIsDetected()
|
||||||
|
{
|
||||||
|
RunTestWithRealm((realm, storage) =>
|
||||||
|
{
|
||||||
|
LoadTestRuleset.HasImplementations = true;
|
||||||
|
LoadTestRuleset.Version = Ruleset.CURRENT_RULESET_API_VERSION;
|
||||||
|
|
||||||
|
var ruleset = new LoadTestRuleset();
|
||||||
|
string rulesetShortName = ruleset.RulesetInfo.ShortName;
|
||||||
|
|
||||||
|
realm.Write(r => r.Add(new RulesetInfo(rulesetShortName, ruleset.RulesetInfo.Name, ruleset.RulesetInfo.InstantiationInfo, 0)
|
||||||
|
{
|
||||||
|
Available = true,
|
||||||
|
}));
|
||||||
|
|
||||||
|
Assert.That(realm.Run(r => r.Find<RulesetInfo>(rulesetShortName)!.Available), Is.True);
|
||||||
|
|
||||||
|
// Availability is updated on construction of a RealmRulesetStore
|
||||||
|
using var _ = new RealmRulesetStore(realm, storage);
|
||||||
|
|
||||||
|
Assert.That(realm.Run(r => r.Find<RulesetInfo>(rulesetShortName)!.Available), Is.False);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestMultipleRulesetWithSameOnlineIdsAreDetected()
|
||||||
|
{
|
||||||
|
RunTestWithRealm((realm, storage) =>
|
||||||
|
{
|
||||||
|
LoadTestRuleset.HasImplementations = true;
|
||||||
|
LoadTestRuleset.Version = Ruleset.CURRENT_RULESET_API_VERSION;
|
||||||
|
LoadTestRuleset.OnlineID = 2;
|
||||||
|
|
||||||
|
var first = new LoadTestRuleset();
|
||||||
|
var second = new CatchRuleset();
|
||||||
|
|
||||||
|
realm.Write(r => r.Add(new RulesetInfo(first.ShortName, first.RulesetInfo.Name, first.RulesetInfo.InstantiationInfo, first.RulesetInfo.OnlineID)
|
||||||
|
{
|
||||||
|
Available = true,
|
||||||
|
}));
|
||||||
|
realm.Write(r => r.Add(new RulesetInfo(second.ShortName, second.RulesetInfo.Name, second.RulesetInfo.InstantiationInfo, second.RulesetInfo.OnlineID)
|
||||||
|
{
|
||||||
|
Available = true,
|
||||||
|
}));
|
||||||
|
|
||||||
|
Assert.That(realm.Run(r => r.Find<RulesetInfo>(first.ShortName)!.Available), Is.True);
|
||||||
|
Assert.That(realm.Run(r => r.Find<RulesetInfo>(second.ShortName)!.Available), Is.True);
|
||||||
|
|
||||||
|
// Availability is updated on construction of a RealmRulesetStore
|
||||||
|
using var _ = new RealmRulesetStore(realm, storage);
|
||||||
|
|
||||||
|
Assert.That(realm.Run(r => r.Find<RulesetInfo>(first.ShortName)!.Available), Is.False);
|
||||||
|
Assert.That(realm.Run(r => r.Find<RulesetInfo>(second.ShortName)!.Available), Is.False);
|
||||||
|
|
||||||
|
realm.Write(r => r.Remove(r.Find<RulesetInfo>(first.ShortName)!));
|
||||||
|
|
||||||
|
using var __ = new RealmRulesetStore(realm, storage);
|
||||||
|
|
||||||
|
Assert.That(realm.Run(r => r.Find<RulesetInfo>(second.ShortName)!.Available), Is.True);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
private class LoadTestRuleset : Ruleset
|
private class LoadTestRuleset : Ruleset
|
||||||
{
|
{
|
||||||
public override string RulesetAPIVersionSupported => Version;
|
public override string RulesetAPIVersionSupported => Version;
|
||||||
@@ -124,6 +188,13 @@ namespace osu.Game.Tests.Database
|
|||||||
|
|
||||||
public static string Version { get; set; } = CURRENT_RULESET_API_VERSION;
|
public static string Version { get; set; } = CURRENT_RULESET_API_VERSION;
|
||||||
|
|
||||||
|
public static int OnlineID { get; set; } = -1;
|
||||||
|
|
||||||
|
public LoadTestRuleset()
|
||||||
|
{
|
||||||
|
RulesetInfo.OnlineID = OnlineID;
|
||||||
|
}
|
||||||
|
|
||||||
public override IEnumerable<Mod> GetModsFor(ModType type)
|
public override IEnumerable<Mod> GetModsFor(ModType type)
|
||||||
{
|
{
|
||||||
if (!HasImplementations)
|
if (!HasImplementations)
|
||||||
|
|||||||
@@ -134,10 +134,12 @@ namespace osu.Game.Tests.Mods
|
|||||||
|
|
||||||
var mod = (OsuModDifficultyAdjust)apiMod.ToMod(ruleset);
|
var mod = (OsuModDifficultyAdjust)apiMod.ToMod(ruleset);
|
||||||
|
|
||||||
|
// WARNING: this only makes sense for debug builds which have very extended limits
|
||||||
|
// release builds still use sane values
|
||||||
Assert.Multiple(() =>
|
Assert.Multiple(() =>
|
||||||
{
|
{
|
||||||
Assert.That(mod.CircleSize.Value, Is.GreaterThanOrEqualTo(0).And.LessThanOrEqualTo(11));
|
Assert.That(mod.CircleSize.Value, Is.GreaterThanOrEqualTo(-250).And.LessThanOrEqualTo(13));
|
||||||
Assert.That(mod.ApproachRate.Value, Is.GreaterThanOrEqualTo(-10).And.LessThanOrEqualTo(11));
|
Assert.That(mod.ApproachRate.Value, Is.GreaterThanOrEqualTo(-250).And.LessThanOrEqualTo(13));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ using osu.Game.Rulesets;
|
|||||||
using osu.Game.Rulesets.Filter;
|
using osu.Game.Rulesets.Filter;
|
||||||
using osu.Game.Rulesets.Mods;
|
using osu.Game.Rulesets.Mods;
|
||||||
using osu.Game.Screens.Select;
|
using osu.Game.Screens.Select;
|
||||||
using osu.Game.Screens.Select.Carousel;
|
|
||||||
using osu.Game.Screens.Select.Filter;
|
using osu.Game.Screens.Select.Filter;
|
||||||
|
|
||||||
namespace osu.Game.Tests.NonVisual.Filtering
|
namespace osu.Game.Tests.NonVisual.Filtering
|
||||||
@@ -588,6 +587,26 @@ namespace osu.Game.Tests.NonVisual.Filtering
|
|||||||
Assert.That(visibleBeatmaps, Is.EqualTo(expectedBeatmapIndexes));
|
Assert.That(visibleBeatmaps, Is.EqualTo(expectedBeatmapIndexes));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This is a temporary class that emulates what these tests originally used from song select v1.
|
||||||
|
// If anyone ever ends up tidying up these test, here's a starting point:
|
||||||
|
// https://gist.github.com/peppy/67fda38f6483fd1dd01ef845ed5bf932
|
||||||
|
public class CarouselBeatmap
|
||||||
|
{
|
||||||
|
public readonly BeatmapInfo BeatmapInfo;
|
||||||
|
|
||||||
|
public BindableBool Filtered = new BindableBool();
|
||||||
|
|
||||||
|
public CarouselBeatmap(BeatmapInfo beatmapInfo)
|
||||||
|
{
|
||||||
|
BeatmapInfo = beatmapInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Filter(FilterCriteria criteria)
|
||||||
|
{
|
||||||
|
Filtered.Value = !BeatmapCarouselFilterMatching.CheckCriteriaMatch(BeatmapInfo, criteria);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private class CustomCriteria : IRulesetFilterCriteria
|
private class CustomCriteria : IRulesetFilterCriteria
|
||||||
{
|
{
|
||||||
private readonly bool match;
|
private readonly bool match;
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ using osu.Game.Beatmaps;
|
|||||||
using osu.Game.Rulesets.Filter;
|
using osu.Game.Rulesets.Filter;
|
||||||
using osu.Game.Rulesets.Mods;
|
using osu.Game.Rulesets.Mods;
|
||||||
using osu.Game.Screens.Select;
|
using osu.Game.Screens.Select;
|
||||||
using osu.Game.Screens.Select.Carousel;
|
|
||||||
using osu.Game.Screens.Select.Filter;
|
using osu.Game.Screens.Select.Filter;
|
||||||
|
|
||||||
namespace osu.Game.Tests.NonVisual.Filtering
|
namespace osu.Game.Tests.NonVisual.Filtering
|
||||||
@@ -509,7 +508,7 @@ namespace osu.Game.Tests.NonVisual.Filtering
|
|||||||
("Another One", "diff ]with [[ brackets]]]"),
|
("Another One", "diff ]with [[ brackets]]]"),
|
||||||
("Diff in title", "a"),
|
("Diff in title", "a"),
|
||||||
("a", "Diff in diff"),
|
("a", "Diff in diff"),
|
||||||
}).Select(info => new CarouselBeatmap(new BeatmapInfo
|
}).Select(info => new FilterMatchingTest.CarouselBeatmap(new BeatmapInfo
|
||||||
{
|
{
|
||||||
Metadata = new BeatmapMetadata
|
Metadata = new BeatmapMetadata
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ namespace osu.Game.Tests.Online
|
|||||||
Assert.NotNull(converted);
|
Assert.NotNull(converted);
|
||||||
Assert.That(converted, Is.TypeOf(typeof(UnknownMod)));
|
Assert.That(converted, Is.TypeOf(typeof(UnknownMod)));
|
||||||
Assert.That(converted.Type, Is.EqualTo(ModType.System));
|
Assert.That(converted.Type, Is.EqualTo(ModType.System));
|
||||||
Assert.That(converted.Acronym, Is.EqualTo("WNG??"));
|
Assert.That(converted.Acronym, Is.EqualTo("WNG!"));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
|
|||||||
@@ -44,7 +44,13 @@ namespace osu.Game.Tests.Online
|
|||||||
availableBeatmap = importedSet.Beatmaps[0];
|
availableBeatmap = importedSet.Beatmaps[0];
|
||||||
unavailableBeatmap = importedSet.Beatmaps[1];
|
unavailableBeatmap = importedSet.Beatmaps[1];
|
||||||
|
|
||||||
Realm.Write(r => r.Remove(r.Find<BeatmapInfo>(unavailableBeatmap.ID)!));
|
Realm.Write(r =>
|
||||||
|
{
|
||||||
|
BeatmapInfo available = r.Find<BeatmapInfo>(availableBeatmap.ID)!;
|
||||||
|
available.OnlineMD5Hash = available.MD5Hash;
|
||||||
|
|
||||||
|
r.Remove(r.Find<BeatmapInfo>(unavailableBeatmap.ID)!);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void SetUpSteps()
|
public override void SetUpSteps()
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ using osu.Framework.Platform;
|
|||||||
using osu.Framework.Testing;
|
using osu.Framework.Testing;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Beatmaps.Formats;
|
using osu.Game.Beatmaps.Formats;
|
||||||
|
using osu.Game.Configuration;
|
||||||
using osu.Game.Database;
|
using osu.Game.Database;
|
||||||
using osu.Game.IO;
|
using osu.Game.IO;
|
||||||
using osu.Game.IO.Archives;
|
using osu.Game.IO.Archives;
|
||||||
@@ -27,6 +28,7 @@ using osu.Game.Screens.OnlinePlay;
|
|||||||
using osu.Game.Screens.OnlinePlay.Playlists;
|
using osu.Game.Screens.OnlinePlay.Playlists;
|
||||||
using osu.Game.Tests.Resources;
|
using osu.Game.Tests.Resources;
|
||||||
using osu.Game.Tests.Visual;
|
using osu.Game.Tests.Visual;
|
||||||
|
using Realms;
|
||||||
|
|
||||||
namespace osu.Game.Tests.Online
|
namespace osu.Game.Tests.Online
|
||||||
{
|
{
|
||||||
@@ -206,7 +208,7 @@ namespace osu.Game.Tests.Online
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override BeatmapImporter CreateBeatmapImporter(Storage storage, RealmAccess realm)
|
protected override BeatmapImporter CreateBeatmapImporter(Storage storage, RealmAccess realm, OsuConfigManager? config = null)
|
||||||
{
|
{
|
||||||
return new TestBeatmapImporter(this, storage, realm);
|
return new TestBeatmapImporter(this, storage, realm);
|
||||||
}
|
}
|
||||||
@@ -216,7 +218,7 @@ namespace osu.Game.Tests.Online
|
|||||||
private readonly TestBeatmapManager testBeatmapManager;
|
private readonly TestBeatmapManager testBeatmapManager;
|
||||||
|
|
||||||
public TestBeatmapImporter(TestBeatmapManager testBeatmapManager, Storage storage, RealmAccess databaseAccess)
|
public TestBeatmapImporter(TestBeatmapManager testBeatmapManager, Storage storage, RealmAccess databaseAccess)
|
||||||
: base(storage, databaseAccess)
|
: base(storage, databaseAccess, null)
|
||||||
{
|
{
|
||||||
this.testBeatmapManager = testBeatmapManager;
|
this.testBeatmapManager = testBeatmapManager;
|
||||||
}
|
}
|
||||||
@@ -224,11 +226,19 @@ namespace osu.Game.Tests.Online
|
|||||||
public override Live<BeatmapSetInfo>? ImportModel(BeatmapSetInfo item, ArchiveReader? archive = null, ImportParameters parameters = default,
|
public override Live<BeatmapSetInfo>? ImportModel(BeatmapSetInfo item, ArchiveReader? archive = null, ImportParameters parameters = default,
|
||||||
CancellationToken cancellationToken = default)
|
CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
if (!testBeatmapManager.AllowImport.Wait(TimeSpan.FromSeconds(10), cancellationToken))
|
if (!testBeatmapManager.AllowImport.Wait(TimeSpan.FromSeconds(30), cancellationToken))
|
||||||
throw new TimeoutException("Timeout waiting for import to be allowed.");
|
throw new TimeoutException("Timeout waiting for import to be allowed.");
|
||||||
|
|
||||||
return testBeatmapManager.CurrentImport = base.ImportModel(item, archive, parameters, cancellationToken);
|
return testBeatmapManager.CurrentImport = base.ImportModel(item, archive, parameters, cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override void PostImport(BeatmapSetInfo model, Realm realm, ImportParameters parameters)
|
||||||
|
{
|
||||||
|
foreach (var beatmap in model.Beatmaps)
|
||||||
|
beatmap.OnlineMD5Hash = beatmap.MD5Hash;
|
||||||
|
|
||||||
|
base.PostImport(model, realm, parameters);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
1590
osu.Game.Tests/Resources/Requests/api-beatmaps-rankedplay.json
Normal file
1590
osu.Game.Tests/Resources/Requests/api-beatmaps-rankedplay.json
Normal file
File diff suppressed because it is too large
Load Diff
@@ -526,7 +526,7 @@ namespace osu.Game.Tests.Rulesets.Scoring
|
|||||||
// ReSharper disable once MemberHidesStaticFromOuterClass
|
// ReSharper disable once MemberHidesStaticFromOuterClass
|
||||||
private class TestRuleset : Ruleset
|
private class TestRuleset : Ruleset
|
||||||
{
|
{
|
||||||
protected override IEnumerable<HitResult> GetValidHitResults() => new[] { HitResult.Great };
|
public override IEnumerable<HitResult> GetValidHitResults() => new[] { HitResult.Great };
|
||||||
|
|
||||||
public override IEnumerable<Mod> GetModsFor(ModType type) => throw new NotImplementedException();
|
public override IEnumerable<Mod> GetModsFor(ModType type) => throw new NotImplementedException();
|
||||||
|
|
||||||
|
|||||||
@@ -83,6 +83,8 @@ namespace osu.Game.Tests.Skins
|
|||||||
"Archives/modified-classic-20250827.osk",
|
"Archives/modified-classic-20250827.osk",
|
||||||
// Covers "Argon" judgement counter
|
// Covers "Argon" judgement counter
|
||||||
"Archives/modified-argon-20250308.osk",
|
"Archives/modified-argon-20250308.osk",
|
||||||
|
// Covers "Argon" clicks/s counter, longest combo counter, skinnable SR display and beatmap status pill
|
||||||
|
"Archives/modified-argon-20251215-jvnkosu.osk",
|
||||||
};
|
};
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user