nonebot-plugin-osubot 6.23.1__py3-none-any.whl → 6.24.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of nonebot-plugin-osubot might be problematic. Click here for more details.

Files changed (81) hide show
  1. nonebot_plugin_osubot/api.py +7 -5
  2. nonebot_plugin_osubot/draw/bmap.py +19 -21
  3. nonebot_plugin_osubot/draw/bp.py +1 -1
  4. nonebot_plugin_osubot/draw/echarts.py +8 -2
  5. nonebot_plugin_osubot/draw/info.py +2 -0
  6. nonebot_plugin_osubot/draw/map.py +5 -2
  7. nonebot_plugin_osubot/draw/osu_preview.py +64 -0
  8. nonebot_plugin_osubot/draw/osu_preview_templates/css/style.css +258 -0
  9. nonebot_plugin_osubot/draw/osu_preview_templates/gif.js/README.md +109 -0
  10. nonebot_plugin_osubot/draw/osu_preview_templates/gif.js/gif.js +3 -0
  11. nonebot_plugin_osubot/draw/osu_preview_templates/gif.js/gif.js.map +1 -0
  12. nonebot_plugin_osubot/draw/osu_preview_templates/gif.js/gif.worker.js +3 -0
  13. nonebot_plugin_osubot/draw/osu_preview_templates/gif.js/gif.worker.js.map +1 -0
  14. nonebot_plugin_osubot/draw/osu_preview_templates/index.html +437 -0
  15. nonebot_plugin_osubot/draw/osu_preview_templates/js/beatmap/beatmap.js +211 -0
  16. nonebot_plugin_osubot/draw/osu_preview_templates/js/beatmap/hitobject.js +29 -0
  17. nonebot_plugin_osubot/draw/osu_preview_templates/js/beatmap/point.js +55 -0
  18. nonebot_plugin_osubot/draw/osu_preview_templates/js/beatmap/scroll.js +45 -0
  19. nonebot_plugin_osubot/draw/osu_preview_templates/js/beatmap/timingpoint.js +35 -0
  20. nonebot_plugin_osubot/draw/osu_preview_templates/js/catch/LegacyRandom.js +81 -0
  21. nonebot_plugin_osubot/draw/osu_preview_templates/js/catch/PalpableCatchHitObject.js +53 -0
  22. nonebot_plugin_osubot/draw/osu_preview_templates/js/catch/bananashower.js +33 -0
  23. nonebot_plugin_osubot/draw/osu_preview_templates/js/catch/catch.js +211 -0
  24. nonebot_plugin_osubot/draw/osu_preview_templates/js/catch/fruit.js +21 -0
  25. nonebot_plugin_osubot/draw/osu_preview_templates/js/catch/juicestream.js +176 -0
  26. nonebot_plugin_osubot/draw/osu_preview_templates/js/mania/hitnote.js +21 -0
  27. nonebot_plugin_osubot/draw/osu_preview_templates/js/mania/holdnote.js +37 -0
  28. nonebot_plugin_osubot/draw/osu_preview_templates/js/mania/mania.js +164 -0
  29. nonebot_plugin_osubot/draw/osu_preview_templates/js/preview.js +61 -0
  30. nonebot_plugin_osubot/draw/osu_preview_templates/js/standard/curve/bezier2.js +33 -0
  31. nonebot_plugin_osubot/draw/osu_preview_templates/js/standard/curve/catmullcurve.js +34 -0
  32. nonebot_plugin_osubot/draw/osu_preview_templates/js/standard/curve/centripetalcatmullrom.js +30 -0
  33. nonebot_plugin_osubot/draw/osu_preview_templates/js/standard/curve/circumstancedcircle.js +47 -0
  34. nonebot_plugin_osubot/draw/osu_preview_templates/js/standard/curve/curve.js +25 -0
  35. nonebot_plugin_osubot/draw/osu_preview_templates/js/standard/curve/curvetype.js +17 -0
  36. nonebot_plugin_osubot/draw/osu_preview_templates/js/standard/curve/equaldistancemulticurve.js +70 -0
  37. nonebot_plugin_osubot/draw/osu_preview_templates/js/standard/curve/linearbezier.js +40 -0
  38. nonebot_plugin_osubot/draw/osu_preview_templates/js/standard/hitcircle.js +85 -0
  39. nonebot_plugin_osubot/draw/osu_preview_templates/js/standard/slider.js +120 -0
  40. nonebot_plugin_osubot/draw/osu_preview_templates/js/standard/spinner.js +56 -0
  41. nonebot_plugin_osubot/draw/osu_preview_templates/js/standard/standard.js +170 -0
  42. nonebot_plugin_osubot/draw/osu_preview_templates/js/taiko/donkat.js +40 -0
  43. nonebot_plugin_osubot/draw/osu_preview_templates/js/taiko/drumroll.js +34 -0
  44. nonebot_plugin_osubot/draw/osu_preview_templates/js/taiko/shaker.js +58 -0
  45. nonebot_plugin_osubot/draw/osu_preview_templates/js/taiko/taiko.js +120 -0
  46. nonebot_plugin_osubot/draw/osu_preview_templates/js/util.js +61 -0
  47. nonebot_plugin_osubot/draw/osu_preview_templates/pic.html +115 -0
  48. nonebot_plugin_osubot/draw/score.py +4 -4
  49. nonebot_plugin_osubot/file.py +1 -12
  50. nonebot_plugin_osubot/mania/__init__.py +9 -10
  51. nonebot_plugin_osubot/matcher/bp_analyze.py +9 -9
  52. nonebot_plugin_osubot/matcher/guess.py +3 -3
  53. nonebot_plugin_osubot/matcher/map_convert.py +12 -7
  54. nonebot_plugin_osubot/matcher/preview.py +10 -3
  55. nonebot_plugin_osubot/matcher/recommend.py +7 -12
  56. nonebot_plugin_osubot/osufile/mods/AP.png +0 -0
  57. nonebot_plugin_osubot/osufile/mods/CL.png +0 -0
  58. nonebot_plugin_osubot/osufile/mods/DT.png +0 -0
  59. nonebot_plugin_osubot/osufile/mods/EZ.png +0 -0
  60. nonebot_plugin_osubot/osufile/mods/FI.png +0 -0
  61. nonebot_plugin_osubot/osufile/mods/FL.png +0 -0
  62. nonebot_plugin_osubot/osufile/mods/HD.png +0 -0
  63. nonebot_plugin_osubot/osufile/mods/HR.png +0 -0
  64. nonebot_plugin_osubot/osufile/mods/HT.png +0 -0
  65. nonebot_plugin_osubot/osufile/mods/MR.png +0 -0
  66. nonebot_plugin_osubot/osufile/mods/NC.png +0 -0
  67. nonebot_plugin_osubot/osufile/mods/NF.png +0 -0
  68. nonebot_plugin_osubot/osufile/mods/PF.png +0 -0
  69. nonebot_plugin_osubot/osufile/mods/RX.png +0 -0
  70. nonebot_plugin_osubot/osufile/mods/SD.png +0 -0
  71. nonebot_plugin_osubot/osufile/mods/SO.png +0 -0
  72. nonebot_plugin_osubot/osufile/mods/TD.png +0 -0
  73. nonebot_plugin_osubot/osufile/mods/V2.png +0 -0
  74. nonebot_plugin_osubot/pp.py +7 -0
  75. nonebot_plugin_osubot/schema/__init__.py +0 -2
  76. nonebot_plugin_osubot/schema/beatmapsets.py +42 -0
  77. nonebot_plugin_osubot/schema/score.py +1 -0
  78. {nonebot_plugin_osubot-6.23.1.dist-info → nonebot_plugin_osubot-6.24.1.dist-info}/METADATA +2 -2
  79. {nonebot_plugin_osubot-6.23.1.dist-info → nonebot_plugin_osubot-6.24.1.dist-info}/RECORD +80 -39
  80. nonebot_plugin_osubot/schema/sayo_beatmap.py +0 -59
  81. {nonebot_plugin_osubot-6.23.1.dist-info → nonebot_plugin_osubot-6.24.1.dist-info}/WHEEL +0 -0
@@ -0,0 +1,70 @@
1
+ function EqualDistanceMultiCurve(curves, pixelLength)
2
+ {
3
+ // https://github.com/itdelatrisu/opsu/blob/master/src/itdelatrisu/opsu/objects/curves/EqualDistanceMultiCurve.java
4
+ var nCurve = pixelLength / Curve.PRECISION | 0;
5
+ this.path = [];
6
+
7
+ var distanceAt = 0,
8
+ curveIndex = 0,
9
+ curve = curves[curveIndex],
10
+ pointIndex = 0,
11
+ startPoint = curve.path[0],
12
+ lastDistanceAt = 0;
13
+ // for each distance, try to get in between the two points that are between it
14
+ for (var i = 0; i <= nCurve; i++)
15
+ {
16
+ var prefDistance = i * pixelLength / nCurve | 0;
17
+ while (distanceAt < prefDistance)
18
+ {
19
+ lastDistanceAt = distanceAt;
20
+ startPoint = curve.path[pointIndex];
21
+
22
+ if (++pointIndex >= curve.path.length)
23
+ {
24
+ if (curveIndex + 1 < curves.length)
25
+ {
26
+ curve = curves[++curveIndex];
27
+ pointIndex = 0;
28
+ }
29
+ else
30
+ {
31
+ pointIndex = curve.path.length - 1;
32
+ if (lastDistanceAt == distanceAt)
33
+ {
34
+ // out of points even though the preferred distance hasn't been reached
35
+ break;
36
+ }
37
+ }
38
+ }
39
+ distanceAt += curve.distance[pointIndex];
40
+ }
41
+ var endPoint = curve.path[pointIndex];
42
+
43
+ // interpolate the point between the two closest distances
44
+ if (distanceAt - lastDistanceAt > 1)
45
+ {
46
+ this.path[i] = Math.lerp(startPoint, endPoint, (prefDistance - lastDistanceAt) / (distanceAt - lastDistanceAt));
47
+ }
48
+ else
49
+ {
50
+ this.path[i] = endPoint;
51
+ }
52
+ }
53
+
54
+ Curve.call(this);
55
+ };
56
+ EqualDistanceMultiCurve.prototype = Object.create(Curve.prototype);
57
+ EqualDistanceMultiCurve.prototype.constructor = EqualDistanceMultiCurve;
58
+ EqualDistanceMultiCurve.prototype.pointAt = function(t)
59
+ {
60
+ var indexF = this.path.length * t,
61
+ index = indexF | 0;
62
+ if (index + 1 < this.path.length)
63
+ {
64
+ return Math.lerp(this.path[index], this.path[index + 1], indexF - index);
65
+ }
66
+ else
67
+ {
68
+ return this.path[this.path.length - 1];
69
+ }
70
+ };
@@ -0,0 +1,40 @@
1
+ function LinearBezier(points, pixelLength, linear)
2
+ {
3
+ // https://github.com/itdelatrisu/opsu/blob/master/src/itdelatrisu/opsu/objects/curves/LinearBezier.java
4
+ var beziers = [],
5
+ controls = [],
6
+ last;
7
+ for (var i = 0; i < points.length; i++)
8
+ {
9
+ var point = points[i];
10
+ if (linear)
11
+ {
12
+ if (typeof last != 'undefined')
13
+ {
14
+ controls.push(point);
15
+ beziers.push(new Bezier2(controls));
16
+ controls = [];
17
+ }
18
+ }
19
+ else if (point.equalTo(last))
20
+ {
21
+ try
22
+ {
23
+ beziers.push(new Bezier2(controls));
24
+ }
25
+ catch (e) {}
26
+ controls = [];
27
+ }
28
+ controls.push(point);
29
+ last = point;
30
+ }
31
+ try
32
+ {
33
+ beziers.push(new Bezier2(controls));
34
+ }
35
+ catch (e) {}
36
+
37
+ EqualDistanceMultiCurve.call(this, beziers, pixelLength);
38
+ };
39
+ LinearBezier.prototype = Object.create(EqualDistanceMultiCurve.prototype);
40
+ LinearBezier.prototype.constructor = LinearBezier;
@@ -0,0 +1,85 @@
1
+ function HitCircle(data, beatmap)
2
+ {
3
+ HitObject.call(this, data, beatmap);
4
+
5
+ this.stack = 0;
6
+ }
7
+ HitCircle.prototype = Object.create(HitObject.prototype, {
8
+ newCombo: {
9
+ get: function()
10
+ {
11
+ return this.flag & 4;
12
+ }
13
+ },
14
+ comboSkip: {
15
+ get: function()
16
+ {
17
+ return this.flag >> 4;
18
+ }
19
+ }
20
+ });
21
+ HitCircle.prototype.constructor = HitCircle;
22
+ HitCircle.ID = 1;
23
+ Standard.prototype.hitObjectTypes[HitCircle.ID] = HitCircle;
24
+ HitCircle.FADE_IN_TIME = 375;
25
+ HitCircle.FADE_OUT_TIME = 200;
26
+ HitCircle.prototype.draw = function(time, ctx)
27
+ {
28
+ var dt = this.time - time,
29
+ opacity = 1;
30
+ if (dt >= 0)
31
+ {
32
+ opacity = (this.beatmap.approachTime - dt) / HitCircle.FADE_IN_TIME;
33
+ }
34
+ else
35
+ {
36
+ opacity = 1 + dt / HitCircle.FADE_OUT_TIME;
37
+ }
38
+ ctx.globalAlpha = Math.max(0, Math.min(opacity, 1));
39
+
40
+ this.drawCircle(this.position, ctx);
41
+ this.drawText(this.position, this.combo, 0, ctx);
42
+ if (dt >= 0)
43
+ {
44
+ this.drawApproach(dt, ctx);
45
+ }
46
+ };
47
+ HitCircle.prototype.drawCircle = function(position, ctx)
48
+ {
49
+ // HitCircle
50
+ ctx.beginPath();
51
+ ctx.arc(position.x - this.stack * this.beatmap.stackOffset,
52
+ position.y - this.stack * this.beatmap.stackOffset,
53
+ this.beatmap.circleRadius - this.beatmap.circleBorder / 2, -Math.PI, Math.PI);
54
+ ctx.shadowBlur = 0;
55
+ ctx.fillStyle = this.color;
56
+ ctx.fill();
57
+ // Overlay
58
+ ctx.shadowBlur = this.beatmap.shadowBlur;
59
+ ctx.strokeStyle = '#fff';
60
+ ctx.lineWidth = this.beatmap.circleBorder;
61
+ ctx.stroke();
62
+ };
63
+ HitCircle.prototype.drawText = function(position, text, deg, ctx)
64
+ {
65
+ ctx.shadowBlur = this.beatmap.shadowBlur;
66
+ ctx.fillStyle = '#fff';
67
+ ctx.save();
68
+ ctx.translate(position.x - this.stack * this.beatmap.stackOffset,
69
+ position.y - this.stack * this.beatmap.stackOffset);
70
+ ctx.rotate(deg);
71
+ ctx.fillText(text, 0, 0);
72
+ ctx.restore();
73
+ };
74
+ HitCircle.prototype.drawApproach = function(dt, ctx)
75
+ {
76
+ var scale = 1 + dt / this.beatmap.approachTime * 3;
77
+ ctx.beginPath();
78
+ ctx.arc(this.position.x - this.stack * this.beatmap.stackOffset,
79
+ this.position.y - this.stack * this.beatmap.stackOffset,
80
+ this.beatmap.circleRadius * scale - this.beatmap.circleBorder / 2, -Math.PI, Math.PI);
81
+ ctx.shadowBlur = 0;
82
+ ctx.strokeStyle = this.color;
83
+ ctx.lineWidth = this.beatmap.circleBorder / 2 * scale;
84
+ ctx.stroke();
85
+ };
@@ -0,0 +1,120 @@
1
+ function Slider(data, beatmap)
2
+ {
3
+ HitCircle.call(this, data, beatmap);
4
+
5
+ var points = data[5].split('|');
6
+ var sliderType = points[0];
7
+ points[0] = this.position;
8
+ for (var i = 1; i < points.length; i++)
9
+ {
10
+ points[i] = new Point(points[i].split(':'));
11
+ }
12
+ this.repeat = data[6] | 0;
13
+ this.pixelLength = +data[7];
14
+
15
+ var sliderTime = this.beatmap.timingPointAt(this.time).beatLength * (
16
+ this.pixelLength / this.beatmap.SliderMultiplier
17
+ ) / 100;
18
+ this.endTime += sliderTime * this.repeat;
19
+ this.duration = this.endTime - this.time;
20
+
21
+ this.curve = Curve.parse(sliderType, points, this.pixelLength);
22
+
23
+ this.endPosition = this.curve.pointAt(1);
24
+ }
25
+ Slider.prototype = Object.create(HitCircle.prototype);
26
+ Slider.prototype.constructor = Slider;
27
+ Slider.ID = 2;
28
+ Standard.prototype.hitObjectTypes[Slider.ID] = Slider;
29
+ Slider.FADE_IN_TIME = 375;
30
+ Slider.FADE_OUT_TIME = 200;
31
+ Slider.REVERSE_ARROW = String.fromCharCode(10132);
32
+ Slider.OPACITY = 0.66;
33
+ Slider.prototype.draw = function(time, ctx)
34
+ {
35
+ var dt = this.time - time,
36
+ opacity = 1;
37
+ if (dt >= 0)
38
+ {
39
+ opacity = (this.beatmap.approachTime - dt) / Slider.FADE_IN_TIME;
40
+ }
41
+ else if (time > this.endTime)
42
+ {
43
+ opacity = 1 - (time - this.endTime) / Slider.FADE_OUT_TIME;
44
+ }
45
+ ctx.globalAlpha = Math.max(0, Math.min(opacity, 1));
46
+
47
+ this.drawPath(ctx);
48
+ // this.drawCircle(this.endPosition, ctx);
49
+ // this.drawCircle(this.position, ctx);
50
+
51
+ var repeat = -dt * this.repeat / this.duration;
52
+ // this.repeat - this.repeat % 2: 홀수면 짝수로 내리기
53
+ if (this.repeat > 1 && repeat + 1 <= (this.repeat & ~1))
54
+ {
55
+ this.drawCircle(this.endPosition, ctx);
56
+ this.drawText(this.endPosition, Slider.REVERSE_ARROW, this.curve.endAngle, ctx);
57
+ }
58
+ // this.repeat - (this.repeat + 1) % 2: 짝수면 홀수로 내리기
59
+ if (repeat > 0 && repeat + 1 <= this.repeat - !(this.repeat & 1))
60
+ {
61
+ this.drawCircle(this.position, ctx);
62
+ this.drawText(this.position, Slider.REVERSE_ARROW, this.curve.startAngle, ctx);
63
+ }
64
+ else if (dt >= 0)
65
+ {
66
+ this.drawCircle(this.position, ctx);
67
+ this.drawText(this.position, this.combo, 0, ctx);
68
+ }
69
+
70
+ if (dt >= 0)
71
+ {
72
+ this.drawApproach(dt, ctx);
73
+ }
74
+ else if (time < this.endTime)
75
+ {
76
+ this.drawFollowCircle(repeat, ctx);
77
+ }
78
+ };
79
+ Slider.prototype.drawPath = function(ctx)
80
+ {
81
+ ctx.save();
82
+ // Slider
83
+ ctx.globalAlpha *= Slider.OPACITY;
84
+ ctx.beginPath();
85
+ ctx.moveTo(this.position.x - this.stack * this.beatmap.stackOffset,
86
+ this.position.y - this.stack * this.beatmap.stackOffset);
87
+ for (var i = 1; i < this.curve.path.length; i++)
88
+ {
89
+ ctx.lineTo(this.curve.path[i].x - this.stack * this.beatmap.stackOffset,
90
+ this.curve.path[i].y - this.stack * this.beatmap.stackOffset);
91
+ }
92
+ ctx.shadowBlur = 0;
93
+ ctx.strokeStyle = this.color;
94
+ ctx.lineWidth = (this.beatmap.circleRadius - this.beatmap.circleBorder) * 2;
95
+ ctx.stroke();
96
+ // Border
97
+ ctx.globalCompositeOperation = 'destination-over';
98
+ ctx.shadowBlur = 0;
99
+ ctx.strokeStyle = '#fff';
100
+ ctx.lineWidth = this.beatmap.circleRadius * 2;
101
+ ctx.stroke();
102
+ ctx.restore();
103
+ };
104
+ Slider.prototype.drawFollowCircle = function(repeat, ctx)
105
+ {
106
+ repeat %= 2;
107
+ if (repeat > 1)
108
+ {
109
+ repeat = 2 - repeat;
110
+ }
111
+ var point = this.curve.pointAt(repeat);
112
+ ctx.beginPath();
113
+ ctx.arc(point.x - this.stack * this.beatmap.stackOffset,
114
+ point.y - this.stack * this.beatmap.stackOffset,
115
+ this.beatmap.circleRadius - this.beatmap.circleBorder / 2, -Math.PI, Math.PI);
116
+ ctx.shadowBlur = this.beatmap.shadowBlur;
117
+ ctx.strokeStyle = '#fff';
118
+ ctx.lineWidth = this.beatmap.circleBorder;
119
+ ctx.stroke();
120
+ }
@@ -0,0 +1,56 @@
1
+ function Spinner(data, beatmap)
2
+ {
3
+ HitCircle.call(this, data, beatmap);
4
+
5
+ this.endTime = data[5] | 0;
6
+ this.duration = this.endTime - this.time;
7
+ }
8
+ Spinner.prototype = Object.create(HitCircle.prototype);
9
+ Spinner.prototype.constructor = Spinner;
10
+ Spinner.ID = 8;
11
+ Standard.prototype.hitObjectTypes[Spinner.ID] = Spinner;
12
+ Spinner.FADE_IN_TIME = 500;
13
+ Spinner.FADE_OUT_TIME = 200;
14
+ Spinner.RADIUS = Beatmap.MAX_Y / 2;
15
+ Spinner.BORDER_WIDTH = Spinner.RADIUS / 20;
16
+ Spinner.prototype.draw = function(time, ctx)
17
+ {
18
+ var dt = this.time - time,
19
+ opacity = 1;
20
+ if (dt >= 0)
21
+ {
22
+ opacity = (this.beatmap.approachTime - dt) / Spinner.FADE_IN_TIME;
23
+ }
24
+ else if (time > this.endTime)
25
+ {
26
+ opacity = 1 - (time - this.endTime) / Spinner.FADE_OUT_TIME;
27
+ }
28
+ ctx.globalAlpha = Math.max(0, Math.min(opacity, 1));
29
+ ctx.save();
30
+ // Spinner
31
+ ctx.beginPath();
32
+ ctx.arc(this.position.x, this.position.y,
33
+ Spinner.RADIUS - Spinner.BORDER_WIDTH / 2, -Math.PI, Math.PI);
34
+ ctx.globalCompositeOperation = 'destination-over';
35
+ ctx.shadowBlur = 0;
36
+ ctx.fillStyle = 'rgba(0,0,0,.4)';
37
+ ctx.fill();
38
+ // Border
39
+ ctx.shadowBlur = Spinner.BORDER_WIDTH;
40
+ ctx.strokeStyle = '#fff';
41
+ ctx.lineWidth = Spinner.BORDER_WIDTH;
42
+ ctx.stroke();
43
+ ctx.restore();
44
+ // Approach
45
+ if (dt < 0 && time <= this.endTime)
46
+ {
47
+ var scale = 1 + dt / this.duration;
48
+ ctx.beginPath();
49
+ ctx.arc(this.position.x, this.position.y,
50
+ (Spinner.RADIUS - Spinner.BORDER_WIDTH / 2) * scale, -Math.PI, Math.PI);
51
+ ctx.shadowBlur = 3;
52
+ ctx.strokeStyle = '#fff';
53
+ ctx.lineWidth = (Spinner.BORDER_WIDTH / 2) * scale;
54
+ ctx.stroke();
55
+ }
56
+ };
@@ -0,0 +1,170 @@
1
+ function Standard(osu)
2
+ {
3
+ Beatmap.call(this, osu);
4
+
5
+ let savedDefaultColor = window.localStorage.getItem("DefaultColor");
6
+ this.useDefaultColor = (savedDefaultColor) ? parseInt(savedDefaultColor) : 0;
7
+
8
+ let savedColorChange = window.localStorage.getItem("ColorChange");
9
+ this.colorChange = (savedColorChange) ? parseInt(savedColorChange) : 0;
10
+
11
+ if (this.Colors.length && !this.useDefaultColor) {
12
+ this.Colors.push(this.Colors.shift());
13
+ }
14
+ else
15
+ {
16
+ this.Colors = Standard.DEFAULT_COLORS;
17
+ }
18
+
19
+ var combo = 1,
20
+ comboIndex = -1,
21
+ setComboIndex = 1;
22
+ for (var i = 0; i < this.HitObjects.length; i++)
23
+ {
24
+ var hitObject = this.HitObjects[i];
25
+ if (hitObject instanceof Spinner)
26
+ {
27
+ setComboIndex = 1;
28
+ }
29
+ else if (hitObject.newCombo || setComboIndex)
30
+ {
31
+ combo = 1;
32
+ comboIndex = ((comboIndex + 1) + hitObject.comboSkip) % this.Colors.length;
33
+ setComboIndex = 0;
34
+ }
35
+ hitObject.combo = combo++;
36
+ hitObject.color = (this.colorChange) ? this.Colors[i % this.Colors.length] : this.Colors[comboIndex];
37
+ }
38
+
39
+
40
+ // calculate stacks
41
+ // https://gist.github.com/peppy/1167470
42
+ for (var i = this.HitObjects.length - 1; i > 0; i--)
43
+ {
44
+ var hitObject = this.HitObjects[i];
45
+ if (hitObject.stack != 0 || hitObject instanceof Spinner)
46
+ {
47
+ continue;
48
+ }
49
+
50
+ for (var n = i - 1; n >= 0; n--)
51
+ {
52
+ var hitObjectN = this.HitObjects[n];
53
+ if (hitObjectN instanceof Spinner)
54
+ {
55
+ continue;
56
+ }
57
+
58
+ if (hitObject.time - hitObjectN.endTime > this.approachTime * this.StackLeniency)
59
+ {
60
+ break;
61
+ }
62
+
63
+ if (hitObject.position.distanceTo(hitObjectN.endPosition) < Standard.STACK_LENIENCE)
64
+ {
65
+ if (hitObjectN instanceof Slider)
66
+ {
67
+ var offset = hitObject.stack - hitObjectN.stack + 1;
68
+ for (var j = n + 1; j <= i; j++)
69
+ {
70
+ var hitObjectJ = this.HitObjects[j];
71
+ if (hitObjectJ.position.distanceTo(hitObjectN.endPosition) < Standard.STACK_LENIENCE)
72
+ {
73
+ hitObjectJ.stack -= offset;
74
+ }
75
+ }
76
+ break;
77
+ }
78
+
79
+ hitObjectN.stack = hitObject.stack + 1;
80
+ hitObject = hitObjectN;
81
+ }
82
+ }
83
+ }
84
+
85
+ this.circleRadius = this.circleDiameter / 2;
86
+ this.circleBorder = this.circleRadius / 8;
87
+ this.shadowBlur = this.circleRadius / 15;
88
+ }
89
+ Standard.prototype = Object.create(Beatmap.prototype, {
90
+ approachTime: {
91
+ get: function()
92
+ {
93
+ return this.ApproachRate < 5
94
+ ? 1800 - this.ApproachRate * 120
95
+ : 1200 - (this.ApproachRate - 5) * 150;
96
+ }
97
+ },
98
+ // https://github.com/itdelatrisu/opsu/commit/8892973d98e04ebaa6656fe2a23749e61a122705
99
+ circleDiameter: {
100
+ get: function()
101
+ {
102
+ return 108.848 - this.CircleSize * 8.9646;
103
+ }
104
+ },
105
+ stackOffset: {
106
+ get: function()
107
+ {
108
+ return this.circleDiameter / 20;
109
+ }
110
+ }
111
+ });
112
+ Standard.prototype.constructor = Standard;
113
+ Standard.prototype.hitObjectTypes = {};
114
+ Standard.ID = 0;
115
+ Beatmap.modes[Standard.ID] = Standard;
116
+ Standard.DEFAULT_COLORS = [
117
+ 'rgb(0,202,0)',
118
+ 'rgb(18,124,255)',
119
+ 'rgb(242,24,57)',
120
+ 'rgb(255,255,0)'
121
+ ];
122
+ Standard.STACK_LENIENCE = 3;
123
+ Standard.prototype.update = function(ctx)
124
+ {
125
+ ctx.shadowColor = '#666';
126
+ ctx.lineCap = 'round';
127
+ ctx.lineJoin = 'round';
128
+ try
129
+ {
130
+ // this code will fail in Firefox(<~ 44)
131
+ // https://bugzilla.mozilla.org/show_bug.cgi?id=941146
132
+ ctx.font = this.circleRadius + 'px "Comic Sans MS", cursive, sans-serif';
133
+ }
134
+ catch (e) {}
135
+ ctx.textAlign = 'center';
136
+ ctx.textBaseline = 'middle';
137
+ ctx.translate((Beatmap.WIDTH - Beatmap.MAX_X) / 2, (Beatmap.HEIGHT - Beatmap.MAX_Y) / 2);
138
+ };
139
+ Standard.prototype.draw = function(time, ctx)
140
+ {
141
+ if (typeof this.tmp.first == 'undefined')
142
+ {
143
+ this.tmp.first = 0;
144
+ this.tmp.last = -1;
145
+ }
146
+
147
+ while (this.tmp.first < this.HitObjects.length)
148
+ {
149
+ var hitObject = this.HitObjects[this.tmp.first];
150
+ if (time <= hitObject.endTime + hitObject.__proto__.constructor.FADE_OUT_TIME)
151
+ {
152
+ break;
153
+ }
154
+ this.tmp.first++;
155
+ }
156
+ while (this.tmp.last + 1 < this.HitObjects.length &&
157
+ time >= this.HitObjects[this.tmp.last + 1].time - this.approachTime)
158
+ {
159
+ this.tmp.last++;
160
+ }
161
+ for (var i = this.tmp.last; i >= this.tmp.first; i--)
162
+ {
163
+ var hitObject = this.HitObjects[i];
164
+ if (time > hitObject.endTime + hitObject.__proto__.constructor.FADE_OUT_TIME)
165
+ {
166
+ continue;
167
+ }
168
+ hitObject.draw(time, ctx);
169
+ }
170
+ };
@@ -0,0 +1,40 @@
1
+ function DonKat(data, beatmap)
2
+ {
3
+ HitCircle.call(this, data, beatmap);
4
+
5
+ }
6
+ DonKat.prototype = Object.create(HitCircle.prototype, {
7
+ don: {
8
+ get: function()
9
+ {
10
+ return !this.kai | 0;
11
+ }
12
+ },
13
+ kai: {
14
+ get: function()
15
+ {
16
+ return ((this.hitSound & 10) != 0) | 0;
17
+ }
18
+ },
19
+ dai: {
20
+ get: function()
21
+ {
22
+ return this.hitSound & 4;
23
+ }
24
+ }
25
+ });
26
+ DonKat.prototype.constructor = DonKat;
27
+ DonKat.ID = 1;
28
+ Taiko.prototype.hitObjectTypes[DonKat.ID] = DonKat;
29
+ DonKat.prototype.draw = function(scroll, ctx)
30
+ {
31
+ var diam = Taiko.DIAMETER * (this.dai ? 1.5 : 1);
32
+ var border = 3;
33
+ ctx.beginPath();
34
+ ctx.arc(this.beatmap.calcX(this.position.x, scroll), 0, diam / 2 - border / 2, -Math.PI, Math.PI);
35
+ ctx.fillStyle = Taiko.DEFAULT_COLORS[this.kai];
36
+ ctx.fill();
37
+ ctx.strokeStyle = '#fff';
38
+ ctx.lineWidth = border;
39
+ ctx.stroke();
40
+ };
@@ -0,0 +1,34 @@
1
+ function Drumroll(data, beatmap)
2
+ {
3
+ Slider.call(this, data, beatmap);
4
+
5
+ }
6
+ Drumroll.prototype = Object.create(Slider.prototype, {});
7
+ Drumroll.prototype.constructor = Drumroll;
8
+ Drumroll.ID = 2;
9
+ Taiko.prototype.hitObjectTypes[Drumroll.ID] = Drumroll;
10
+ Drumroll.prototype.draw = function(scroll, ctx)
11
+ {
12
+ var diam = Taiko.DIAMETER;
13
+ var border = 3;
14
+
15
+ ctx.beginPath();
16
+ ctx.moveTo(this.beatmap.calcX(this.position.x, scroll), 0);
17
+ ctx.lineTo(this.beatmap.calcX(this.endPosition.x, scroll), 0);
18
+
19
+ ctx.strokeStyle = '#333';
20
+ ctx.lineWidth = diam;
21
+ ctx.stroke();
22
+
23
+ ctx.strokeStyle = Taiko.DEFAULT_COLORS[2];
24
+ ctx.lineWidth = diam - border;
25
+ ctx.stroke();
26
+
27
+ ctx.beginPath();
28
+ ctx.arc(this.beatmap.calcX(this.position.x, scroll), 0, diam / 2 - border / 2, -Math.PI, Math.PI);
29
+ ctx.fillStyle = Taiko.DEFAULT_COLORS[2];
30
+ ctx.fill();
31
+ ctx.strokeStyle = '#fff';
32
+ ctx.lineWidth = border;
33
+ ctx.stroke();
34
+ };
@@ -0,0 +1,58 @@
1
+ function Shaker(data, beatmap)
2
+ {
3
+ Spinner.call(this, data, beatmap);
4
+
5
+ }
6
+ Shaker.prototype = Object.create(Spinner.prototype, {});
7
+ Shaker.prototype.constructor = Shaker;
8
+ Shaker.ID = 8;
9
+ Taiko.prototype.hitObjectTypes[Shaker.ID] = Shaker;
10
+ Shaker.prototype.draw = function(scroll, ctx)
11
+ {
12
+ var ds = this.beatmap.calcX(this.position.x, scroll);
13
+ if (ds > 0)
14
+ {
15
+ var diam = Taiko.DIAMETER * 1.5;
16
+ var border = 3;
17
+ ctx.beginPath();
18
+ ctx.arc(this.beatmap.calcX(this.position.x, scroll), 0, diam / 2 - border / 2, -Math.PI, Math.PI);
19
+ ctx.fillStyle = Taiko.DEFAULT_COLORS[2];
20
+ ctx.fill();
21
+ ctx.strokeStyle = '#fff';
22
+ ctx.lineWidth = border;
23
+ ctx.stroke();
24
+ }
25
+ else
26
+ {
27
+ ctx.save();
28
+ ctx.setTransform(1, 0, 0, 1, 0, 0);
29
+ ctx.translate(Beatmap.WIDTH / 2, Beatmap.HEIGHT / 2);
30
+ // Spinner
31
+ ctx.beginPath();
32
+ ctx.arc(0, 0,
33
+ Spinner.RADIUS - Spinner.BORDER_WIDTH / 2, -Math.PI, Math.PI);
34
+ ctx.globalCompositeOperation = 'destination-over';
35
+ ctx.shadowBlur = 0;
36
+ ctx.fillStyle = 'rgba(0,0,0,.4)';
37
+ ctx.fill();
38
+ // Border
39
+ ctx.shadowBlur = Spinner.BORDER_WIDTH;
40
+ ctx.strokeStyle = '#fff';
41
+ ctx.lineWidth = Spinner.BORDER_WIDTH;
42
+ ctx.stroke();
43
+ // Approach
44
+ if (ds < 0 && scroll <= this.endPosition.x)
45
+ {
46
+ var scale = 1 + ds / this.beatmap.calcX(this.endPosition.x, this.position.x);
47
+ ctx.beginPath();
48
+ ctx.arc(0, 0,
49
+ (Spinner.RADIUS - Spinner.BORDER_WIDTH / 2) * scale, -Math.PI, Math.PI);
50
+ ctx.globalCompositeOperation = 'source-over';
51
+ ctx.shadowBlur = 3;
52
+ ctx.strokeStyle = '#fff';
53
+ ctx.lineWidth = (Spinner.BORDER_WIDTH / 2) * scale;
54
+ ctx.stroke();
55
+ }
56
+ ctx.restore();
57
+ }
58
+ };