nonebot-plugin-osubot 6.24.0__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 (46) hide show
  1. nonebot_plugin_osubot/draw/osu_preview.py +64 -0
  2. nonebot_plugin_osubot/draw/osu_preview_templates/css/style.css +258 -0
  3. nonebot_plugin_osubot/draw/osu_preview_templates/gif.js/README.md +109 -0
  4. nonebot_plugin_osubot/draw/osu_preview_templates/gif.js/gif.js +3 -0
  5. nonebot_plugin_osubot/draw/osu_preview_templates/gif.js/gif.js.map +1 -0
  6. nonebot_plugin_osubot/draw/osu_preview_templates/gif.js/gif.worker.js +3 -0
  7. nonebot_plugin_osubot/draw/osu_preview_templates/gif.js/gif.worker.js.map +1 -0
  8. nonebot_plugin_osubot/draw/osu_preview_templates/index.html +437 -0
  9. nonebot_plugin_osubot/draw/osu_preview_templates/js/beatmap/beatmap.js +211 -0
  10. nonebot_plugin_osubot/draw/osu_preview_templates/js/beatmap/hitobject.js +29 -0
  11. nonebot_plugin_osubot/draw/osu_preview_templates/js/beatmap/point.js +55 -0
  12. nonebot_plugin_osubot/draw/osu_preview_templates/js/beatmap/scroll.js +45 -0
  13. nonebot_plugin_osubot/draw/osu_preview_templates/js/beatmap/timingpoint.js +35 -0
  14. nonebot_plugin_osubot/draw/osu_preview_templates/js/catch/LegacyRandom.js +81 -0
  15. nonebot_plugin_osubot/draw/osu_preview_templates/js/catch/PalpableCatchHitObject.js +53 -0
  16. nonebot_plugin_osubot/draw/osu_preview_templates/js/catch/bananashower.js +33 -0
  17. nonebot_plugin_osubot/draw/osu_preview_templates/js/catch/catch.js +211 -0
  18. nonebot_plugin_osubot/draw/osu_preview_templates/js/catch/fruit.js +21 -0
  19. nonebot_plugin_osubot/draw/osu_preview_templates/js/catch/juicestream.js +176 -0
  20. nonebot_plugin_osubot/draw/osu_preview_templates/js/mania/hitnote.js +21 -0
  21. nonebot_plugin_osubot/draw/osu_preview_templates/js/mania/holdnote.js +37 -0
  22. nonebot_plugin_osubot/draw/osu_preview_templates/js/mania/mania.js +164 -0
  23. nonebot_plugin_osubot/draw/osu_preview_templates/js/preview.js +61 -0
  24. nonebot_plugin_osubot/draw/osu_preview_templates/js/standard/curve/bezier2.js +33 -0
  25. nonebot_plugin_osubot/draw/osu_preview_templates/js/standard/curve/catmullcurve.js +34 -0
  26. nonebot_plugin_osubot/draw/osu_preview_templates/js/standard/curve/centripetalcatmullrom.js +30 -0
  27. nonebot_plugin_osubot/draw/osu_preview_templates/js/standard/curve/circumstancedcircle.js +47 -0
  28. nonebot_plugin_osubot/draw/osu_preview_templates/js/standard/curve/curve.js +25 -0
  29. nonebot_plugin_osubot/draw/osu_preview_templates/js/standard/curve/curvetype.js +17 -0
  30. nonebot_plugin_osubot/draw/osu_preview_templates/js/standard/curve/equaldistancemulticurve.js +70 -0
  31. nonebot_plugin_osubot/draw/osu_preview_templates/js/standard/curve/linearbezier.js +40 -0
  32. nonebot_plugin_osubot/draw/osu_preview_templates/js/standard/hitcircle.js +85 -0
  33. nonebot_plugin_osubot/draw/osu_preview_templates/js/standard/slider.js +120 -0
  34. nonebot_plugin_osubot/draw/osu_preview_templates/js/standard/spinner.js +56 -0
  35. nonebot_plugin_osubot/draw/osu_preview_templates/js/standard/standard.js +170 -0
  36. nonebot_plugin_osubot/draw/osu_preview_templates/js/taiko/donkat.js +40 -0
  37. nonebot_plugin_osubot/draw/osu_preview_templates/js/taiko/drumroll.js +34 -0
  38. nonebot_plugin_osubot/draw/osu_preview_templates/js/taiko/shaker.js +58 -0
  39. nonebot_plugin_osubot/draw/osu_preview_templates/js/taiko/taiko.js +120 -0
  40. nonebot_plugin_osubot/draw/osu_preview_templates/js/util.js +61 -0
  41. nonebot_plugin_osubot/draw/osu_preview_templates/pic.html +115 -0
  42. nonebot_plugin_osubot/matcher/preview.py +7 -0
  43. nonebot_plugin_osubot/pp.py +7 -0
  44. {nonebot_plugin_osubot-6.24.0.dist-info → nonebot_plugin_osubot-6.24.1.dist-info}/METADATA +2 -2
  45. {nonebot_plugin_osubot-6.24.0.dist-info → nonebot_plugin_osubot-6.24.1.dist-info}/RECORD +46 -5
  46. {nonebot_plugin_osubot-6.24.0.dist-info → nonebot_plugin_osubot-6.24.1.dist-info}/WHEEL +0 -0
@@ -0,0 +1,211 @@
1
+ function Catch(osu) {
2
+ Beatmap.call(this, osu);
3
+
4
+ let savedDefaultColor = window.localStorage.getItem("DefaultColor");
5
+ this.useDefaultColor = (savedDefaultColor) ? parseInt(savedDefaultColor) : 0;
6
+
7
+ let savedColorChange = window.localStorage.getItem("ColorChange");
8
+ this.colorChange = (savedColorChange) ? parseInt(savedColorChange) : 0;
9
+
10
+ if (this.Colors.length && !this.useDefaultColor) {
11
+ this.Colors.push(this.Colors.shift());
12
+ }
13
+ else {
14
+ this.Colors = Catch.DEFAULT_COLORS;
15
+ }
16
+
17
+ this.circleRadius = this.circleDiameter / 2 - 4;
18
+ this.smallRadius = this.circleRadius / 2;
19
+ this.tinyRadius = this.smallRadius / 2;
20
+ this.bananaRadius = this.circleRadius * 0.8;
21
+
22
+ this.CATCHER_HEIGHT = Beatmap.HEIGHT / 8;
23
+ this.FALLOUT_TIME = (this.CATCHER_HEIGHT / Beatmap.HEIGHT) * this.approachTime;
24
+
25
+ var combo = 1,
26
+ comboIndex = -1,
27
+ setComboIndex = 1;
28
+ for (var i = 0; i < this.HitObjects.length; i++) {
29
+ let hitObject = this.HitObjects[i];
30
+ if (hitObject instanceof BananaShower) {
31
+ setComboIndex = 1;
32
+ }
33
+ else if (hitObject.newCombo || setComboIndex) {
34
+ combo = 1;
35
+ comboIndex = ((comboIndex + 1) + hitObject.comboSkip) % this.Colors.length;
36
+ setComboIndex = 0;
37
+ }
38
+ hitObject.combo = combo++;
39
+ hitObject.color = (this.colorChange) ? this.Colors[i % this.Colors.length] : this.Colors[comboIndex];
40
+
41
+ if (hitObject instanceof JuiceStream || hitObject instanceof BananaShower) {
42
+ hitObject.buildNested();
43
+ }
44
+ }
45
+
46
+ this.CATCHER_BASE_SIZE = 106.75;
47
+ this.ALLOWED_CATCH_RANGE = 0.8;
48
+ this.HYPER_DASH_TRANSITION_DURATION = 180;
49
+ this.calculateScale = 1.0 - 0.7 * (this.CircleSize - 5) / 5;
50
+ this.catchWidth = this.CATCHER_BASE_SIZE * Math.abs(this.calculateScale) * this.ALLOWED_CATCH_RANGE;
51
+ this.halfCatcherWidth = this.catchWidth / 2;
52
+ this.halfCatcherWidth /= this.ALLOWED_CATCH_RANGE;
53
+ this.BASE_DASH_SPEED = 1;
54
+ this.BASE_WALK_SPEED = 0.5;
55
+
56
+ // sliders & spins xoffset
57
+ this.RNG_SEED = 1337;
58
+ var rng = new LegacyRandom(this.RNG_SEED);
59
+
60
+ for (var i = 0; i < this.HitObjects.length; i++) {
61
+ let hitObject = this.HitObjects[i];
62
+ // console.log(hitObject.nested)
63
+ if (hitObject instanceof BananaShower) {
64
+ hitObject.nested.forEach(banana => {
65
+ banana.x += (rng.NextDouble() * Beatmap.MAX_X);
66
+ rng.Next(); // osu!stable retrieved a random banana type
67
+ rng.Next(); // osu!stable retrieved a random banana rotation
68
+ rng.Next(); // osu!stable retrieved a random banana colour
69
+ });
70
+ }
71
+ else if (hitObject instanceof JuiceStream) {
72
+ hitObject.nested.forEach(item => {
73
+ if (item.type === "TinyDroplet") item.x += Math.clamp(rng.Next(-20, 20), -item.x, Beatmap.MAX_X - item.x);
74
+ else if (item.type === "Droplet") rng.Next(); // osu!stable retrieved a random droplet rotation
75
+ });
76
+ }
77
+ }
78
+
79
+ // catch objects
80
+ this.palpableObjects = [];
81
+ this.fullCatchObjects = [];
82
+ for (var i = 0; i < this.HitObjects.length; i++) {
83
+ let hitObject = this.HitObjects[i];
84
+ if (hitObject instanceof Fruit) {
85
+ let pch = new PalpableCatchHitObject({
86
+ type: "Fruit",
87
+ time: hitObject.time,
88
+ x: hitObject.position.x,
89
+ color: hitObject.color,
90
+ radius: this.circleRadius,
91
+ }, this);
92
+
93
+ this.palpableObjects.push(pch);
94
+ this.fullCatchObjects.push(pch);
95
+ }
96
+ else if (hitObject instanceof BananaShower) {
97
+ hitObject.nested.forEach(banana => {
98
+ this.fullCatchObjects.push(banana);
99
+ });
100
+ }
101
+ else if (hitObject instanceof JuiceStream) {
102
+ hitObject.nested.forEach(item => {
103
+ this.fullCatchObjects.push(item);
104
+ if (item.type != "TinyDroplet") this.palpableObjects.push(item);
105
+ });
106
+ }
107
+ }
108
+
109
+ this.palpableObjects.sort((a, b) => a.time - b.time);
110
+ this.fullCatchObjects.sort((a, b) => a.time - b.time);
111
+
112
+ // hyperdash
113
+ let lastDirection = 0;
114
+ let lastExcess = this.halfCatcherWidth;
115
+
116
+ for (let i = 0; i < this.palpableObjects.length - 1; i++) {
117
+ var currentObject = this.palpableObjects[i];
118
+ var nextObject = this.palpableObjects[i + 1];
119
+
120
+ currentObject.hyperDash = false;
121
+
122
+ let thisDirection = nextObject.x > currentObject.x ? 1 : -1;
123
+ let timeToNext = nextObject.time - currentObject.time - 1000 / 60 / 4; // 1/4th of a frame of grace time, taken from osu-stable
124
+ let distanceToNext = Math.abs(nextObject.x - currentObject.x) - (lastDirection == thisDirection ? lastExcess : this.halfCatcherWidth);
125
+ let distanceToHyper = timeToNext * this.BASE_DASH_SPEED - distanceToNext;
126
+
127
+ if (distanceToHyper < 0) {
128
+ currentObject.hyperDash = true;
129
+ lastExcess = this.halfCatcherWidth;
130
+ }
131
+ else {
132
+ lastExcess = Math.clamp(distanceToHyper, 0, this.halfCatcherWidth);
133
+ }
134
+
135
+ lastDirection = thisDirection;
136
+ }
137
+
138
+ }
139
+ Catch.prototype = Object.create(Beatmap.prototype, {
140
+ approachTime: { // droptime
141
+ get: function () {
142
+ return this.ApproachRate < 5
143
+ ? 1800 - this.ApproachRate * 120
144
+ : 1200 - (this.ApproachRate - 5) * 150;
145
+ }
146
+ },
147
+ // https://github.com/itdelatrisu/opsu/commit/8892973d98e04ebaa6656fe2a23749e61a122705
148
+ circleDiameter: {
149
+ get: function () {
150
+ return 108.848 - this.CircleSize * 8.9646;
151
+ }
152
+ }
153
+ });
154
+ Catch.prototype.constructor = Catch;
155
+ Catch.prototype.hitObjectTypes = {};
156
+ Catch.ID = 2;
157
+ Beatmap.modes[Catch.ID] = Catch;
158
+ Catch.DEFAULT_COLORS = [
159
+ 'rgb(255,210,128)',
160
+ 'rgb(128,255,128)',
161
+ 'rgb(128,191,255)',
162
+ 'rgb(191,128,255)'
163
+ ];
164
+ Catch.prototype.update = function (ctx) {
165
+ ctx.translate((Beatmap.WIDTH - Beatmap.MAX_X) / 2, (Beatmap.HEIGHT - Beatmap.MAX_Y) / 2);
166
+ };
167
+ Catch.prototype.draw = function (time, ctx) {
168
+ if (typeof this.tmp.first == 'undefined') {
169
+ this.tmp.first = 0;
170
+ this.tmp.last = -1;
171
+ }
172
+
173
+ while (this.tmp.first < this.fullCatchObjects.length) {
174
+ var catchHitObject = this.fullCatchObjects[this.tmp.first];
175
+ if (time <= catchHitObject.time + this.FALLOUT_TIME) {
176
+ break;
177
+ }
178
+ this.tmp.first++;
179
+ }
180
+ while (this.tmp.last + 1 < this.fullCatchObjects.length &&
181
+ time >= this.fullCatchObjects[this.tmp.last + 1].time - this.approachTime * 1.1) {
182
+ this.tmp.last++;
183
+ }
184
+ for (var i = this.tmp.last; i >= this.tmp.first; i--) {
185
+ var catchHitObject = this.fullCatchObjects[i];
186
+ if (time > catchHitObject.time + this.FALLOUT_TIME) {
187
+ continue;
188
+ }
189
+ catchHitObject.draw(time, ctx);
190
+ }
191
+ };
192
+ Catch.prototype.processBG = function (ctx) {
193
+ let xoffset = (Beatmap.WIDTH - Beatmap.MAX_X) / 2;
194
+ let yoffset = (Beatmap.HEIGHT - Beatmap.MAX_Y) / 2;
195
+ // line
196
+ ctx.beginPath();
197
+ ctx.moveTo(-xoffset, Beatmap.HEIGHT - this.CATCHER_HEIGHT - yoffset);
198
+ ctx.lineTo(Beatmap.WIDTH - xoffset, Beatmap.HEIGHT - this.CATCHER_HEIGHT - yoffset);
199
+ ctx.strokeStyle = '#fff';
200
+ ctx.lineWidth = 1;
201
+ ctx.stroke();
202
+ // plate
203
+ let plateHeight = 20;
204
+ ctx.beginPath();
205
+ ctx.rect(Beatmap.WIDTH / 2 - this.catchWidth / 2 - xoffset, Beatmap.HEIGHT - this.CATCHER_HEIGHT - plateHeight / 2 - yoffset, this.catchWidth, plateHeight);
206
+ ctx.strokeStyle = '#fff';
207
+ ctx.lineWidth = 8;
208
+ ctx.stroke();
209
+ ctx.fillStyle = '#fff';
210
+ ctx.fill();
211
+ };
@@ -0,0 +1,21 @@
1
+ function Fruit(data, beatmap)
2
+ {
3
+ HitObject.call(this, data, beatmap);
4
+ }
5
+ Fruit.prototype = Object.create(HitObject.prototype, {
6
+ newCombo: {
7
+ get: function()
8
+ {
9
+ return this.flag & 4;
10
+ }
11
+ },
12
+ comboSkip: {
13
+ get: function()
14
+ {
15
+ return this.flag >> 4;
16
+ }
17
+ }
18
+ });
19
+ Fruit.prototype.constructor = Fruit;
20
+ Fruit.ID = 1;
21
+ Catch.prototype.hitObjectTypes[Fruit.ID] = Fruit;
@@ -0,0 +1,176 @@
1
+ function JuiceStream(data, beatmap)
2
+ {
3
+ Slider.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
+ this.timingPoint = this.beatmap.timingPointAt(this.time);
16
+ this.beatLength = this.timingPoint.beatLength;
17
+ this.timingPointStart = this.timingPoint.time;
18
+
19
+ this.sliderTime = this.beatLength * ( this.pixelLength / this.beatmap.SliderMultiplier ) / 100;
20
+ this.velocityFactor = 100 * this.beatmap.SliderMultiplier / this.beatLength;
21
+ this.tickDistanceFactor = 100 * this.beatmap.SliderMultiplier / this.beatmap.SliderTickRate;
22
+ this.velocity = this.velocityFactor * this.timingPoint.sliderVelocity;
23
+ this.tickDistance = this.tickDistanceFactor * this.timingPoint.sliderVelocity;
24
+
25
+ this.endTime = this.time + this.sliderTime * this.repeat;
26
+ this.duration = this.endTime - this.time;
27
+
28
+ this.spanCount = parseInt(this.repeat);
29
+
30
+ this.curve = Curve.parse(sliderType, points, this.pixelLength);
31
+
32
+ this.endPosition = this.curve.pointAt(1);
33
+
34
+ this.max_length = 100000;
35
+ let length = Math.min(this.max_length, this.pixelLength);
36
+ this.tickDistance = Math.clamp(this.tickDistance, 0, length);
37
+ this.minDistanceFromEnd = this.velocity * 10;
38
+
39
+ this.events = [];
40
+ this.events.push({type: "head", time: this.time, pathProgress: 0});
41
+ if (this.tickDistance != 0) {
42
+ for (let span = 0; span < this.spanCount; span++) {
43
+ let spanStartTime = this.time + span * this.sliderTime;
44
+ let reversed = span % 2 == 1;
45
+ let ticks = this.generateTicks(span, spanStartTime, this.sliderTime, reversed, length, this.tickDistance, this.minDistanceFromEnd);
46
+ if (reversed) ticks = ticks.reverse();
47
+ this.events.push(...ticks);
48
+ if (span < this.spanCount - 1)
49
+ {
50
+ this.events.push({
51
+ type: "repeat",
52
+ time: spanStartTime + this.sliderTime,
53
+ pathProgress: (span + 1) % 2
54
+ });
55
+ }
56
+ }
57
+ }
58
+
59
+ let legacyLastTickOffset = 36;
60
+ let finalSpanIndex = this.spanCount - 1;
61
+ let finalSpanStartTime = this.time + finalSpanIndex * this.sliderTime;
62
+ let finalSpanEndTime = Math.max(this.time + this.duration / 2, (finalSpanStartTime + this.sliderTime) - legacyLastTickOffset);
63
+ let finalProgress = (finalSpanEndTime - finalSpanStartTime) / this.sliderTime;
64
+
65
+ if (this.spanCount % 2 == 0) finalProgress = 1 - finalProgress;
66
+
67
+ this.events.push({
68
+ type: "legacyLastTick",
69
+ time: finalSpanEndTime,
70
+ pathProgress: finalProgress
71
+ });
72
+
73
+ this.events.push({
74
+ type: "tail",
75
+ time: this.endTime,
76
+ pathProgress: this.spanCount % 2
77
+ });
78
+
79
+ this.nested = [];
80
+ }
81
+ JuiceStream.prototype = Object.create(Slider.prototype);
82
+ JuiceStream.prototype.constructor = JuiceStream;
83
+ JuiceStream.ID = 2;
84
+ Catch.prototype.hitObjectTypes[JuiceStream.ID] = JuiceStream;
85
+ JuiceStream.prototype.generateTicks = function(spanIndex, spanStartTime, spanDuration, reversed, length, tickDistance, minDistanceFromEnd) {
86
+ let ticks = [];
87
+ for (let d = tickDistance; d <= length; d += tickDistance) {
88
+ if (d >= length - minDistanceFromEnd)
89
+ break;
90
+
91
+ let pathProgress = d / length;
92
+ let timeProgress = reversed ? 1 - pathProgress : pathProgress;
93
+
94
+ ticks.push({type: "tick", time: spanStartTime + timeProgress * spanDuration, pathProgress});
95
+ }
96
+ return ticks;
97
+ }
98
+
99
+ JuiceStream.prototype.buildNested = function() {
100
+ this.nested = [];
101
+
102
+ let lastEvent = null;
103
+ for(let i = 0; i < this.events.length; i++) {
104
+ // generate tiny droplets since the last point
105
+ if (lastEvent != null)
106
+ {
107
+ let sinceLastTick = this.events[i].time - lastEvent.time;
108
+ if (sinceLastTick > 80)
109
+ {
110
+ let timeBetweenTiny = sinceLastTick;
111
+ while (timeBetweenTiny > 100) timeBetweenTiny /= 2;
112
+ for (let t = timeBetweenTiny; t < sinceLastTick; t += timeBetweenTiny) {
113
+ let repeat = (t + lastEvent.time - this.time) * this.repeat / this.duration;
114
+ repeat %= 2;
115
+ if (repeat > 1) repeat = 2 - repeat;
116
+ var point = this.curve.pointAt(repeat);
117
+ this.nested.push(new PalpableCatchHitObject({
118
+ type: "TinyDroplet",
119
+ time: t + lastEvent.time,
120
+ x: point.x,
121
+ // x: this.curve.pointAt(lastEvent.pathProgress + (t / sinceLastTick) * (this.events[i].pathProgress - lastEvent.pathProgress)).x,
122
+ color: this.color,
123
+ radius: this.beatmap.tinyRadius,
124
+ }, this.beatmap));
125
+ }
126
+ }
127
+ }
128
+
129
+ // this also includes LegacyLastTick and this is used for TinyDroplet generation above.
130
+ // this means that the final segment of TinyDroplets are increasingly mistimed where LegacyLastTickOffset is being applied.
131
+ lastEvent = this.events[i];
132
+
133
+ switch (this.events[i].type)
134
+ {
135
+ case "tick":
136
+ this.nested.push(new PalpableCatchHitObject({
137
+ type: "Droplet",
138
+ time: this.events[i].time,
139
+ x: this.curve.pointAt(this.events[i].pathProgress).x,
140
+ color: this.color,
141
+ radius: this.beatmap.smallRadius,
142
+ }, this.beatmap));
143
+ break;
144
+
145
+ case "head":
146
+ case "tail":
147
+ case "repeat":
148
+ this.nested.push(new PalpableCatchHitObject({
149
+ type: "Fruit",
150
+ time: this.events[i].time,
151
+ x: this.curve.pointAt(this.events[i].pathProgress).x,
152
+ color: this.color,
153
+ radius: this.beatmap.circleRadius,
154
+ }, this.beatmap));
155
+ break;
156
+ }
157
+ }
158
+
159
+ /* TODO BUG!!!
160
+ * 在预览 #4057684 时第一个滑条出现了
161
+ * PalpableCatchHitObject {beatmap: Catch, type: 'TinyDroplet', time: 464.57142857142895, …}
162
+ * PalpableCatchHitObject {beatmap: Catch, type: 'Droplet', time: 464.571428571429, …}
163
+ * 物件数量偏差导致后续随机数错误
164
+ * 暂时找不到原因,可能因为计算精度问题,临时手动将其剔除
165
+ */
166
+ let tmp_droplets = this.nested.filter((item) => item.type === "Droplet");
167
+ this.nested = this.nested.filter((item) => {
168
+ if (item.type != "TinyDroplet") return true;
169
+ for (let td = 0; td < tmp_droplets.length; td++) {
170
+ if (Math.abs(item.time - tmp_droplets[td].time) < 0.01) return false;
171
+ }
172
+ return true;
173
+ });
174
+
175
+ return this;
176
+ }
@@ -0,0 +1,21 @@
1
+ function HitNote(data, beatmap)
2
+ {
3
+ HitObject.call(this, data, beatmap);
4
+
5
+ this.column = Math.max(1, Math.min((this.position.x / this.beatmap.columnSize + 1) | 0, this.beatmap.keyCount)) - 1;
6
+ }
7
+ HitNote.prototype = Object.create(HitObject.prototype);
8
+ HitNote.prototype.constructor = HitNote;
9
+ HitNote.ID = 1;
10
+ Mania.prototype.hitObjectTypes[HitNote.ID] = HitNote;
11
+ HitNote.prototype.draw = function(scroll, ctx)
12
+ {
13
+ ctx.beginPath();
14
+ ctx.rect(this.position.x, this.beatmap.calcY(this.position.y, scroll) - Mania.COLUMN_WIDTH / 3,
15
+ Mania.COLUMN_WIDTH, Mania.COLUMN_WIDTH / 3);
16
+ ctx.fillStyle = this.color;
17
+ ctx.fill();
18
+ ctx.strokeStyle = '#ccc';
19
+ ctx.lineWidth = 1;
20
+ ctx.stroke();
21
+ };
@@ -0,0 +1,37 @@
1
+ function HoldNote(data, beatmap)
2
+ {
3
+ HitNote.call(this, data, beatmap);
4
+
5
+ this.endTime = data[5].split(':')[0] | 0;
6
+ }
7
+ HoldNote.prototype = Object.create(HitNote.prototype);
8
+ HoldNote.prototype.constructor = HoldNote;
9
+ HoldNote.ID = 128;
10
+ Mania.prototype.hitObjectTypes[HoldNote.ID] = HoldNote;
11
+ HoldNote.WIDTH_SCALE = 0.8;
12
+ HoldNote.OPACITY = 0.88;
13
+ HoldNote.prototype.draw = function(scroll, ctx)
14
+ {
15
+ var sy = this.beatmap.calcY(this.position.y, scroll) - Mania.COLUMN_WIDTH / 3,
16
+ ey = this.beatmap.calcY(this.endPosition.y, scroll) - Mania.COLUMN_WIDTH / 3;
17
+
18
+ var w = Mania.COLUMN_WIDTH * HoldNote.WIDTH_SCALE;
19
+ ctx.globalAlpha = HoldNote.OPACITY;
20
+ ctx.beginPath();
21
+ ctx.rect(this.position.x + (Mania.COLUMN_WIDTH - w) / 2, ey, w, sy - ey);
22
+ ctx.fillStyle = this.color;
23
+ ctx.fill();
24
+ ctx.globalAlpha = 1;
25
+
26
+ ctx.beginPath();
27
+ ctx.rect(this.position.x, sy, Mania.COLUMN_WIDTH, Mania.COLUMN_WIDTH / 3);
28
+ ctx.fill();
29
+ ctx.strokeStyle = '#ccc';
30
+ ctx.lineWidth = 1;
31
+ ctx.stroke();
32
+
33
+ ctx.beginPath();
34
+ ctx.rect(this.position.x, ey, Mania.COLUMN_WIDTH, Mania.COLUMN_WIDTH / 3);
35
+ ctx.fill();
36
+ ctx.stroke();
37
+ };
@@ -0,0 +1,164 @@
1
+ function Mania(osu)
2
+ {
3
+ Scroll.call(this, osu);
4
+
5
+
6
+ this.scrollSpeed = Mania.SCROLL_SPEED;
7
+ //this.columnStart = Mania.COLUMN_START;
8
+ this.columnStart = (Beatmap.WIDTH - Mania.COLUMN_WIDTH * this.keyCount) / 2
9
+
10
+ for (var i = 0; i < this.keyCount; i++)
11
+ {
12
+ this.Colors[i] = Mania.DEFAULT_COLORS[i & 1];
13
+ }
14
+ var p = this.keyCount / 2;
15
+ if (this.keyCount & 1)
16
+ {
17
+ this.Colors[p | 0] = Mania.DEFAULT_COLORS[2];
18
+ }
19
+ else
20
+ {
21
+ this.Colors = this.Colors.slice(0, p).concat(this.Colors.slice(p - 1));
22
+ }
23
+
24
+
25
+ for (var i = 0; i < this.HitObjects.length; i++)
26
+ {
27
+ var hitObject = this.HitObjects[i];
28
+ hitObject.color = this.Colors[hitObject.column];
29
+ hitObject.position.x = Mania.COLUMN_WIDTH * hitObject.column;
30
+ hitObject.position.y = this.scrollAt(hitObject.time);
31
+ hitObject.endPosition.y = this.scrollAt(hitObject.endTime);
32
+ }
33
+ }
34
+ Mania.prototype = Object.create(Scroll.prototype, {
35
+ keyCount: {
36
+ get: function()
37
+ {
38
+ return this.CircleSize;
39
+ }
40
+ },
41
+ columnSize: {
42
+ get: function()
43
+ {
44
+ return Beatmap.MAX_X / this.keyCount;
45
+ }
46
+ }
47
+ });
48
+ Mania.prototype.constructor = Mania;
49
+ Mania.prototype.hitObjectTypes = {};
50
+ Mania.ID = 3;
51
+ Beatmap.modes[Mania.ID] = Mania;
52
+ Mania.DEFAULT_COLORS = [
53
+ '#5bf',
54
+ '#ccc',
55
+ '#da2'
56
+ ];
57
+ Mania.COLUMN_START = 130;
58
+ Mania.HIT_POSITION = 400;
59
+ Mania.COLUMN_WIDTH = 30;
60
+ let savedSpeed = window.localStorage.getItem("SCROLL_SPEED");
61
+ Mania.SCROLL_SPEED = (savedSpeed) ? parseInt(savedSpeed) : 20;
62
+ Mania.prototype.calcY = function(y, scroll)
63
+ {
64
+ return Mania.HIT_POSITION - (y - scroll) * this.scrollSpeed * 0.035;
65
+ };
66
+ Mania.prototype.update = function(ctx)
67
+ {
68
+ ctx.translate(this.columnStart, 0);
69
+ };
70
+ Mania.prototype.draw = function(time, ctx)
71
+ {
72
+ if (typeof this.tmp.first == 'undefined')
73
+ {
74
+ this.tmp.first = 0;
75
+ this.tmp.last = -1;
76
+ this.tmp.barLine = 0;
77
+ }
78
+
79
+ var scroll = this.scrollAt(time);
80
+ while (this.tmp.first < this.HitObjects.length &&
81
+ time > this.HitObjects[this.tmp.first].endTime)
82
+ {
83
+ this.tmp.first++;
84
+ }
85
+ while (this.tmp.last + 1 < this.HitObjects.length)
86
+ {
87
+ var hitObject = this.HitObjects[this.tmp.last + 1];
88
+ if (this.calcY(hitObject.position.y, scroll) < -Mania.COLUMN_WIDTH)
89
+ {
90
+ break;
91
+ }
92
+ this.tmp.last++;
93
+ }
94
+ while (this.tmp.barLine < this.barLines.length &&
95
+ this.calcY(this.barLines[this.tmp.barLine], scroll) > Beatmap.MAX_Y)
96
+ {
97
+ this.tmp.barLine++;
98
+ }
99
+ for (var i = this.tmp.barLine; i < this.barLines.length && this.calcY(this.barLines[i], scroll) > -Mania.COLUMN_WIDTH; i++)
100
+ {
101
+ var barLine = this.calcY(this.barLines[i], scroll);
102
+ ctx.beginPath();
103
+ ctx.moveTo(0, barLine);
104
+ ctx.lineTo(Mania.COLUMN_WIDTH * this.keyCount, barLine);
105
+ ctx.strokeStyle = '#fff';
106
+ ctx.lineWidth = 1;
107
+ ctx.stroke();
108
+ }
109
+ for (var i = this.tmp.first; i <= this.tmp.last; i++)
110
+ {
111
+ var hitObject = this.HitObjects[i];
112
+ if (time > hitObject.endTime)
113
+ {
114
+ continue;
115
+ }
116
+ hitObject.draw(scroll, ctx);
117
+ }
118
+ ctx.clearRect(0, Mania.HIT_POSITION, Beatmap.WIDTH, Beatmap.HEIGHT - Mania.HIT_POSITION);
119
+ };
120
+ Mania.prototype.processBG = function(ctx)
121
+ {
122
+ ctx.beginPath();
123
+ ctx.rect(0, 0, Mania.COLUMN_WIDTH * this.keyCount, Beatmap.HEIGHT);
124
+ ctx.strokeStyle = '#ddd';
125
+ ctx.lineWidth = 8;
126
+ ctx.stroke();
127
+ ctx.fillStyle = '#000';
128
+ ctx.fill();
129
+
130
+ for (var i = 0; i < this.keyCount; i++)
131
+ {
132
+ var x = Mania.COLUMN_WIDTH * i;
133
+
134
+ ctx.beginPath();
135
+ ctx.moveTo(x, 0);
136
+ ctx.lineTo(x, Mania.HIT_POSITION);
137
+ ctx.strokeStyle = '#fff';
138
+ ctx.lineWidth = 1;
139
+ ctx.stroke();
140
+
141
+ ctx.beginPath();
142
+ ctx.rect(x, Mania.HIT_POSITION, Mania.COLUMN_WIDTH, Beatmap.HEIGHT - Mania.HIT_POSITION);
143
+ ctx.fillStyle = this.Colors[i];
144
+ ctx.fill();
145
+ ctx.strokeStyle = '#fff';
146
+ ctx.lineWidth = 3;
147
+ ctx.stroke();
148
+ }
149
+ var x = Mania.COLUMN_WIDTH * this.keyCount;
150
+ ctx.beginPath();
151
+ ctx.moveTo(x, 0);
152
+ ctx.lineTo(x, Mania.HIT_POSITION);
153
+ ctx.strokeStyle = '#fff';
154
+ ctx.lineWidth = 1;
155
+ ctx.stroke();
156
+ // HIT POSITION
157
+ ctx.beginPath();
158
+ ctx.rect(0, Mania.HIT_POSITION, Mania.COLUMN_WIDTH * this.keyCount, Mania.COLUMN_WIDTH / 3);
159
+ ctx.strokeStyle = '#fff';
160
+ ctx.lineWidth = 2;
161
+ ctx.stroke();
162
+ ctx.fillStyle = '#568';
163
+ ctx.fill();
164
+ };
@@ -0,0 +1,61 @@
1
+ var bgblob;
2
+ function Preview(SCALE = 0.2) {
3
+ this.screen = document.createElement('canvas');
4
+ this.screen.width = Beatmap.WIDTH;
5
+ this.screen.height = Beatmap.HEIGHT;
6
+ this.ctx = this.screen.getContext('2d');
7
+ this.ctx.scale(SCALE, SCALE);
8
+ this.startTime = 0;
9
+ this.endTime = 0;
10
+ this.previewTime = -1;
11
+
12
+ var self = this;
13
+ }
14
+ Preview.prototype.load = function (osufile, success, fail) {
15
+ if (typeof this.xhr != 'undefined') {
16
+ this.xhr.abort();
17
+ }
18
+
19
+ var self = this;
20
+ try {
21
+ self.beatmap = Beatmap.parse(osufile);
22
+
23
+ self.ctx.restore();
24
+ self.ctx.save();
25
+ self.beatmap.update(self.ctx);
26
+ self.at(0);
27
+
28
+ self.previewTime = self.beatmap.PreviewTime > 0 ? self.beatmap.PreviewTime : -1;
29
+
30
+ self.startTime = self.beatmap.HitObjects.length > 0 ? self.beatmap.HitObjects[0].time - 1000 : 0;
31
+ if (self.startTime < 0) {
32
+ self.startTime = 0;
33
+ }
34
+ self.endTime = self.beatmap.HitObjects.length > 0 ? self.beatmap.HitObjects[self.beatmap.HitObjects.length - 1].endTime : 0;
35
+
36
+ if (typeof success == 'function') {
37
+ success.call(self);
38
+ }
39
+ }
40
+ catch (e) {
41
+ if (typeof fail == 'function') {
42
+ fail.call(self, e);
43
+ }
44
+ }
45
+ };
46
+ Preview.prototype.at = function (time) {
47
+ if (time > this.endTime) {
48
+ time = this.endTime;
49
+ }
50
+ if (time < this.startTime) {
51
+ time = this.startTime;
52
+ }
53
+ this.ctx.save();
54
+ this.ctx.setTransform(1, 0, 0, 1, 0, 0);
55
+ this.ctx.clearRect(0, 0, Beatmap.WIDTH, Beatmap.HEIGHT);
56
+ this.ctx.restore();
57
+ if (typeof this.beatmap.processBG != 'undefined') {
58
+ this.beatmap.processBG(this.ctx);
59
+ }
60
+ this.beatmap.draw(time, this.ctx);
61
+ };