nonebot-plugin-osubot 6.24.0__py3-none-any.whl → 6.24.2__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 (45) 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/js/beatmap/beatmap.js +211 -0
  9. nonebot_plugin_osubot/draw/osu_preview_templates/js/beatmap/hitobject.js +29 -0
  10. nonebot_plugin_osubot/draw/osu_preview_templates/js/beatmap/point.js +55 -0
  11. nonebot_plugin_osubot/draw/osu_preview_templates/js/beatmap/scroll.js +45 -0
  12. nonebot_plugin_osubot/draw/osu_preview_templates/js/beatmap/timingpoint.js +35 -0
  13. nonebot_plugin_osubot/draw/osu_preview_templates/js/catch/LegacyRandom.js +81 -0
  14. nonebot_plugin_osubot/draw/osu_preview_templates/js/catch/PalpableCatchHitObject.js +53 -0
  15. nonebot_plugin_osubot/draw/osu_preview_templates/js/catch/bananashower.js +33 -0
  16. nonebot_plugin_osubot/draw/osu_preview_templates/js/catch/catch.js +211 -0
  17. nonebot_plugin_osubot/draw/osu_preview_templates/js/catch/fruit.js +21 -0
  18. nonebot_plugin_osubot/draw/osu_preview_templates/js/catch/juicestream.js +176 -0
  19. nonebot_plugin_osubot/draw/osu_preview_templates/js/mania/hitnote.js +21 -0
  20. nonebot_plugin_osubot/draw/osu_preview_templates/js/mania/holdnote.js +37 -0
  21. nonebot_plugin_osubot/draw/osu_preview_templates/js/mania/mania.js +164 -0
  22. nonebot_plugin_osubot/draw/osu_preview_templates/js/preview.js +61 -0
  23. nonebot_plugin_osubot/draw/osu_preview_templates/js/standard/curve/bezier2.js +33 -0
  24. nonebot_plugin_osubot/draw/osu_preview_templates/js/standard/curve/catmullcurve.js +34 -0
  25. nonebot_plugin_osubot/draw/osu_preview_templates/js/standard/curve/centripetalcatmullrom.js +30 -0
  26. nonebot_plugin_osubot/draw/osu_preview_templates/js/standard/curve/circumstancedcircle.js +47 -0
  27. nonebot_plugin_osubot/draw/osu_preview_templates/js/standard/curve/curve.js +25 -0
  28. nonebot_plugin_osubot/draw/osu_preview_templates/js/standard/curve/curvetype.js +17 -0
  29. nonebot_plugin_osubot/draw/osu_preview_templates/js/standard/curve/equaldistancemulticurve.js +70 -0
  30. nonebot_plugin_osubot/draw/osu_preview_templates/js/standard/curve/linearbezier.js +40 -0
  31. nonebot_plugin_osubot/draw/osu_preview_templates/js/standard/hitcircle.js +85 -0
  32. nonebot_plugin_osubot/draw/osu_preview_templates/js/standard/slider.js +120 -0
  33. nonebot_plugin_osubot/draw/osu_preview_templates/js/standard/spinner.js +56 -0
  34. nonebot_plugin_osubot/draw/osu_preview_templates/js/standard/standard.js +170 -0
  35. nonebot_plugin_osubot/draw/osu_preview_templates/js/taiko/donkat.js +40 -0
  36. nonebot_plugin_osubot/draw/osu_preview_templates/js/taiko/drumroll.js +34 -0
  37. nonebot_plugin_osubot/draw/osu_preview_templates/js/taiko/shaker.js +58 -0
  38. nonebot_plugin_osubot/draw/osu_preview_templates/js/taiko/taiko.js +120 -0
  39. nonebot_plugin_osubot/draw/osu_preview_templates/js/util.js +61 -0
  40. nonebot_plugin_osubot/draw/osu_preview_templates/pic.html +110 -0
  41. nonebot_plugin_osubot/matcher/preview.py +7 -0
  42. nonebot_plugin_osubot/pp.py +7 -0
  43. {nonebot_plugin_osubot-6.24.0.dist-info → nonebot_plugin_osubot-6.24.2.dist-info}/METADATA +2 -2
  44. {nonebot_plugin_osubot-6.24.0.dist-info → nonebot_plugin_osubot-6.24.2.dist-info}/RECORD +45 -5
  45. {nonebot_plugin_osubot-6.24.0.dist-info → nonebot_plugin_osubot-6.24.2.dist-info}/WHEEL +0 -0
@@ -0,0 +1,33 @@
1
+ function BananaShower(data, beatmap) {
2
+ Spinner.call(this, data, beatmap);
3
+
4
+ this.endTime = data[5] | 0;
5
+ this.duration = this.endTime - this.time;
6
+
7
+ this.nested = [];
8
+ }
9
+ BananaShower.prototype = Object.create(Spinner.prototype);
10
+ BananaShower.prototype.constructor = BananaShower;
11
+ BananaShower.ID = 8;
12
+ Catch.prototype.hitObjectTypes[BananaShower.ID] = BananaShower;
13
+ BananaShower.prototype.buildNested = function() {
14
+ this.nested = [];
15
+ let spacing = this.duration;
16
+ while (spacing > 100) spacing /= 2;
17
+ if (spacing <= 0) return;
18
+ let time = this.time;
19
+ let i = 0;
20
+ while (time <= this.endTime) {
21
+ this.nested.push(new PalpableCatchHitObject({
22
+ type: "Banana",
23
+ time,
24
+ x: 0,
25
+ color: 'rgb(255,240,0)',
26
+ radius: this.beatmap.bananaRadius,
27
+ }, this.beatmap));
28
+
29
+ time += spacing;
30
+ i++;
31
+ }
32
+ return this;
33
+ };
@@ -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
+ };