@minicode-dev/chat 0.1.12 → 0.1.14
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.
- package/CHANGELOG.md +112 -5
- package/README.md +401 -309
- package/assets/sounds/effects/avalanche.mp3 +0 -0
- package/assets/sounds/racing/car_boost.mp3 +0 -0
- package/assets/sounds/racing/car_boost.ogg +0 -0
- package/assets/sounds/racing/car_bump.mp3 +0 -0
- package/assets/sounds/racing/car_bump.ogg +0 -0
- package/assets/sounds/racing/car_drift_loop.mp3 +0 -0
- package/assets/sounds/racing/car_drift_loop.ogg +0 -0
- package/assets/sounds/racing/car_engine_loop.mp3 +0 -0
- package/assets/sounds/racing/car_engine_loop.ogg +0 -0
- package/assets/sounds/racing/car_engine_start.mp3 +0 -0
- package/assets/sounds/racing/car_engine_start.ogg +0 -0
- package/assets/sounds/racing/countdown_beep.mp3 +0 -0
- package/assets/sounds/racing/countdown_beep.ogg +0 -0
- package/assets/sounds/racing/countdown_go.mp3 +0 -0
- package/assets/sounds/racing/countdown_go.ogg +0 -0
- package/assets/sounds/racing/final_lap.mp3 +0 -0
- package/assets/sounds/racing/final_lap.ogg +0 -0
- package/assets/sounds/racing/finish_line.mp3 +0 -0
- package/assets/sounds/racing/finish_line.ogg +0 -0
- package/assets/sounds/racing/lap_complete.mp3 +0 -0
- package/assets/sounds/racing/lap_complete.ogg +0 -0
- package/assets/sounds/racing/music_circuit.mp3 +0 -0
- package/assets/sounds/racing/music_circuit.ogg +0 -0
- package/assets/sounds/racing/music_final_lap.mp3 +0 -0
- package/assets/sounds/racing/music_final_lap.ogg +0 -0
- package/assets/sounds/racing/race_defeat.mp3 +0 -0
- package/assets/sounds/racing/race_defeat.ogg +0 -0
- package/assets/sounds/racing/race_victory.mp3 +0 -0
- package/assets/sounds/racing/race_victory.ogg +0 -0
- package/assets/sounds/tanks/barrel_explode.mp3 +0 -0
- package/assets/sounds/tanks/barrel_explode.ogg +0 -0
- package/assets/sounds/tanks/crate_break.mp3 +0 -0
- package/assets/sounds/tanks/crate_break.ogg +0 -0
- package/assets/sounds/tanks/health_pickup.mp3 +0 -0
- package/assets/sounds/tanks/health_pickup.ogg +0 -0
- package/assets/sounds/tanks/last_life.mp3 +0 -0
- package/assets/sounds/tanks/last_life.ogg +0 -0
- package/assets/sounds/tanks/life_lost.mp3 +0 -0
- package/assets/sounds/tanks/life_lost.ogg +0 -0
- package/assets/sounds/tanks/respawn.mp3 +0 -0
- package/assets/sounds/tanks/respawn.ogg +0 -0
- package/assets/sounds/tanks/shield_end.mp3 +0 -0
- package/assets/sounds/tanks/shield_end.ogg +0 -0
- package/assets/sounds/tanks/shield_loop.mp3 +0 -0
- package/assets/sounds/tanks/shield_loop.ogg +0 -0
- package/assets/sounds/tanks/wall_hit.mp3 +0 -0
- package/assets/sounds/tanks/wall_hit.ogg +0 -0
- package/dist/chunks/{BattleshipGameCard-iRk8d4vR.js → BattleshipGameCard-B-B4r7lK.js} +146 -144
- package/dist/chunks/{BattleshipGameCard-iRk8d4vR.js.map → BattleshipGameCard-B-B4r7lK.js.map} +1 -1
- package/dist/chunks/{ChatContext-DjIEifGY.js → ChatContext-DQtKsR6Z.js} +2 -2
- package/dist/chunks/{ChatContext-DjIEifGY.js.map → ChatContext-DQtKsR6Z.js.map} +1 -1
- package/dist/chunks/RacingLiveGameCard-c1G7uoDI.js +1654 -0
- package/dist/chunks/RacingLiveGameCard-c1G7uoDI.js.map +1 -0
- package/dist/chunks/{TanksGameCard-B47ZQcSr.js → TanksGameCard-CvTaF7tu.js} +164 -162
- package/dist/chunks/{TanksGameCard-B47ZQcSr.js.map → TanksGameCard-CvTaF7tu.js.map} +1 -1
- package/dist/chunks/TanksLiveGameCard-COr9Oay5.js +1011 -0
- package/dist/chunks/TanksLiveGameCard-COr9Oay5.js.map +1 -0
- package/dist/chunks/avalancheScene3d-Z5QyZIid.js +1299 -0
- package/dist/chunks/avalancheScene3d-Z5QyZIid.js.map +1 -0
- package/dist/chunks/connect4Sounds-DmD-E9kX.js +235 -0
- package/dist/chunks/connect4Sounds-DmD-E9kX.js.map +1 -0
- package/dist/chunks/connectionStore-DwgIUl30.js +13 -0
- package/dist/chunks/connectionStore-DwgIUl30.js.map +1 -0
- package/dist/chunks/createLiveScene-CWBunxPi.js +367 -0
- package/dist/chunks/createLiveScene-CWBunxPi.js.map +1 -0
- package/dist/chunks/createRaceScene-C7Rw89kj.js +305 -0
- package/dist/chunks/createRaceScene-C7Rw89kj.js.map +1 -0
- package/dist/chunks/{createTankScene-CV7Brxmt.js → createTankScene-yhX6la27.js} +150 -147
- package/dist/chunks/{createTankScene-CV7Brxmt.js.map → createTankScene-yhX6la27.js.map} +1 -1
- package/dist/chunks/decor-CyyCnmct.js +418 -0
- package/dist/chunks/decor-CyyCnmct.js.map +1 -0
- package/dist/chunks/fx-1ZwzmPWj.js +458 -0
- package/dist/chunks/fx-1ZwzmPWj.js.map +1 -0
- package/dist/chunks/fx-UZwhOmdl.js +584 -0
- package/dist/chunks/fx-UZwhOmdl.js.map +1 -0
- package/dist/chunks/gameStatus-BChd29yI.js +62 -0
- package/dist/chunks/gameStatus-BChd29yI.js.map +1 -0
- package/dist/chunks/{connect4Sounds-Cv0q31VW.js → games-BvYTWgaR.js} +814 -951
- package/dist/chunks/games-BvYTWgaR.js.map +1 -0
- package/dist/chunks/rolldown-runtime-CGnMp29N.js +10 -0
- package/dist/chunks/tank-DjEQ4FXF.js +553 -0
- package/dist/chunks/tank-DjEQ4FXF.js.map +1 -0
- package/dist/chunks/tanks-live-BcKmrhnV.js +261 -0
- package/dist/chunks/tanks-live-BcKmrhnV.js.map +1 -0
- package/dist/chunks/{tanksSounds-CUNDIOal.js → tanksSounds-DwjfSp3W.js} +43 -11
- package/dist/chunks/tanksSounds-DwjfSp3W.js.map +1 -0
- package/dist/chunks/track-BcnnpnAm.js +259 -0
- package/dist/chunks/track-BcnnpnAm.js.map +1 -0
- package/dist/chunks/util-DwI9bfS7.js +57 -0
- package/dist/chunks/util-DwI9bfS7.js.map +1 -0
- package/dist/index.js +2176 -1592
- package/dist/index.js.map +1 -1
- package/dist/styles.css +1 -1
- package/index.d.ts +4 -2
- package/package.json +1 -1
- package/dist/chunks/TanksLiveGameCard-DGsnMD3j.js +0 -1225
- package/dist/chunks/TanksLiveGameCard-DGsnMD3j.js.map +0 -1
- package/dist/chunks/connect4Sounds-Cv0q31VW.js.map +0 -1
- package/dist/chunks/createLiveScene-BqI7qV4n.js +0 -364
- package/dist/chunks/createLiveScene-BqI7qV4n.js.map +0 -1
- package/dist/chunks/fx-BHsl4S_J.js +0 -1470
- package/dist/chunks/fx-BHsl4S_J.js.map +0 -1
- package/dist/chunks/gameStatus-Cu1Z8un9.js +0 -69
- package/dist/chunks/gameStatus-Cu1Z8un9.js.map +0 -1
- package/dist/chunks/tanksSounds-CUNDIOal.js.map +0 -1
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
// src/games/racing-live/logic/classes.js
|
|
2
|
+
var e = Object.freeze([
|
|
3
|
+
"50cc",
|
|
4
|
+
"100cc",
|
|
5
|
+
"200cc",
|
|
6
|
+
"400cc",
|
|
7
|
+
"500cc"
|
|
8
|
+
]), t = "200cc", n = Object.freeze({
|
|
9
|
+
laps: 3,
|
|
10
|
+
trackLength: 600,
|
|
11
|
+
trackWidth: 10
|
|
12
|
+
}), r = {
|
|
13
|
+
reverseSpeed: 10,
|
|
14
|
+
grassDrag: 4,
|
|
15
|
+
barrierMargin: 3,
|
|
16
|
+
barrierBounce: .22,
|
|
17
|
+
steeringRate: 1.65
|
|
18
|
+
}, i = (e) => Math.round(e * 1e7) / 1e7;
|
|
19
|
+
function a({ id: e, label: t, topKmh: n, laps: a, trackLength: o, trackWidth: s, acceleration: c, braking: l, rollingDrag: u, lateralGrip: d, driftGrip: f, steerFalloffSpeed: p }) {
|
|
20
|
+
let m = n / 3.6, h = Object.freeze({
|
|
21
|
+
...r,
|
|
22
|
+
maxSpeed: i(m * 1.05),
|
|
23
|
+
acceleration: c,
|
|
24
|
+
braking: l,
|
|
25
|
+
rollingDrag: u,
|
|
26
|
+
airDrag: i((c - u * m) / (m * m)),
|
|
27
|
+
lateralGrip: d,
|
|
28
|
+
driftGrip: f,
|
|
29
|
+
steerFalloffSpeed: p
|
|
30
|
+
});
|
|
31
|
+
return Object.freeze({
|
|
32
|
+
id: e,
|
|
33
|
+
label: t,
|
|
34
|
+
topKmh: n,
|
|
35
|
+
laps: a,
|
|
36
|
+
trackLength: o,
|
|
37
|
+
trackWidth: s,
|
|
38
|
+
rules: h
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
var o = Object.freeze({
|
|
42
|
+
"50cc": a({
|
|
43
|
+
id: "50cc",
|
|
44
|
+
label: "50cc",
|
|
45
|
+
topKmh: 80,
|
|
46
|
+
laps: 3,
|
|
47
|
+
trackLength: 600,
|
|
48
|
+
trackWidth: 10,
|
|
49
|
+
acceleration: 11,
|
|
50
|
+
braking: 20,
|
|
51
|
+
rollingDrag: .3,
|
|
52
|
+
lateralGrip: 10,
|
|
53
|
+
driftGrip: 2.5,
|
|
54
|
+
steerFalloffSpeed: 40
|
|
55
|
+
}),
|
|
56
|
+
"100cc": a({
|
|
57
|
+
id: "100cc",
|
|
58
|
+
label: "100cc",
|
|
59
|
+
topKmh: 130,
|
|
60
|
+
laps: 3,
|
|
61
|
+
trackLength: 600,
|
|
62
|
+
trackWidth: 10,
|
|
63
|
+
acceleration: 15,
|
|
64
|
+
braking: 26,
|
|
65
|
+
rollingDrag: .3,
|
|
66
|
+
lateralGrip: 11,
|
|
67
|
+
driftGrip: 2.7,
|
|
68
|
+
steerFalloffSpeed: 50
|
|
69
|
+
}),
|
|
70
|
+
"200cc": a({
|
|
71
|
+
id: "200cc",
|
|
72
|
+
label: "200cc",
|
|
73
|
+
topKmh: 200,
|
|
74
|
+
laps: 3,
|
|
75
|
+
trackLength: 1200,
|
|
76
|
+
trackWidth: 12,
|
|
77
|
+
acceleration: 21,
|
|
78
|
+
braking: 34,
|
|
79
|
+
rollingDrag: .3,
|
|
80
|
+
lateralGrip: 13,
|
|
81
|
+
driftGrip: 3,
|
|
82
|
+
steerFalloffSpeed: 65
|
|
83
|
+
}),
|
|
84
|
+
"400cc": a({
|
|
85
|
+
id: "400cc",
|
|
86
|
+
label: "400cc",
|
|
87
|
+
topKmh: 300,
|
|
88
|
+
laps: 3,
|
|
89
|
+
trackLength: 2e3,
|
|
90
|
+
trackWidth: 14,
|
|
91
|
+
acceleration: 29,
|
|
92
|
+
braking: 45,
|
|
93
|
+
rollingDrag: .3,
|
|
94
|
+
lateralGrip: 15,
|
|
95
|
+
driftGrip: 3.4,
|
|
96
|
+
steerFalloffSpeed: 90
|
|
97
|
+
}),
|
|
98
|
+
"500cc": a({
|
|
99
|
+
id: "500cc",
|
|
100
|
+
label: "500cc",
|
|
101
|
+
topKmh: 380,
|
|
102
|
+
laps: 4,
|
|
103
|
+
trackLength: 2e3,
|
|
104
|
+
trackWidth: 14,
|
|
105
|
+
acceleration: 35,
|
|
106
|
+
braking: 52,
|
|
107
|
+
rollingDrag: .3,
|
|
108
|
+
lateralGrip: 16,
|
|
109
|
+
driftGrip: 3.6,
|
|
110
|
+
steerFalloffSpeed: 105
|
|
111
|
+
})
|
|
112
|
+
}), s = (t) => typeof t == "string" && e.includes(t), c = (e) => s(e) ? o[e] : null, l = Object.freeze(["neon_city"]), u = 128, d = 3, f = (e) => Math.round(e * 1e6) / 1e6, p = (e, t) => Math.hypot(t.x - e.x, t.z - e.z);
|
|
113
|
+
function m(e) {
|
|
114
|
+
let t = 2166136261;
|
|
115
|
+
for (let n = 0; n < e.length; n += 1) t ^= e.charCodeAt(n), t = Math.imul(t, 16777619);
|
|
116
|
+
return (t >>> 0).toString(16).padStart(8, "0");
|
|
117
|
+
}
|
|
118
|
+
function h(e) {
|
|
119
|
+
if (typeof e == "string") return parseInt(m(e), 16);
|
|
120
|
+
if (typeof e != "number" || !Number.isFinite(e)) throw TypeError("Race seed must be a finite number or string");
|
|
121
|
+
return Math.trunc(e) >>> 0;
|
|
122
|
+
}
|
|
123
|
+
function g(e, t) {
|
|
124
|
+
let n = e[(t + u - 1) % u], r = e[(t + 1) % u], i = p(n, r);
|
|
125
|
+
return {
|
|
126
|
+
x: (r.x - n.x) / i,
|
|
127
|
+
z: (r.z - n.z) / i
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
function _(e, t) {
|
|
131
|
+
if (!Number.isFinite(t)) throw TypeError("Track distance must be finite");
|
|
132
|
+
let n = (t % e.length + e.length) % e.length, r = e.points.length - 2;
|
|
133
|
+
for (let t = 0; t < e.points.length - 1; t += 1) if (n < e.points[t + 1].s) {
|
|
134
|
+
r = t;
|
|
135
|
+
break;
|
|
136
|
+
}
|
|
137
|
+
let i = e.points[r], a = e.points[r + 1], o = a.s - i.s, s = (n - i.s) / o;
|
|
138
|
+
return {
|
|
139
|
+
x: i.x + (a.x - i.x) * s,
|
|
140
|
+
z: i.z + (a.z - i.z) * s,
|
|
141
|
+
s: n,
|
|
142
|
+
segment: r,
|
|
143
|
+
tangent: {
|
|
144
|
+
x: (a.x - i.x) / o,
|
|
145
|
+
z: (a.z - i.z) / o
|
|
146
|
+
}
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
function v(e, t) {
|
|
150
|
+
if (!Number.isFinite(t?.x) || !Number.isFinite(t?.z)) throw TypeError("Position must contain finite x and z");
|
|
151
|
+
let n;
|
|
152
|
+
for (let r = 0; r < e.points.length - 1; r += 1) {
|
|
153
|
+
let i = e.points[r], a = e.points[r + 1], o = a.x - i.x, s = a.z - i.z, c = o * o + s * s, l = Math.min(1, Math.max(0, ((t.x - i.x) * o + (t.z - i.z) * s) / c)), u = i.x + o * l, d = i.z + s * l, f = Math.hypot(t.x - u, t.z - d);
|
|
154
|
+
if (!n || f < n.distance) {
|
|
155
|
+
let a = Math.sqrt(c), p = {
|
|
156
|
+
x: o / a,
|
|
157
|
+
z: s / a
|
|
158
|
+
}, m = (t.x - u) * -p.z + (t.z - d) * p.x;
|
|
159
|
+
n = {
|
|
160
|
+
x: u,
|
|
161
|
+
z: d,
|
|
162
|
+
point: {
|
|
163
|
+
x: u,
|
|
164
|
+
z: d
|
|
165
|
+
},
|
|
166
|
+
distance: f,
|
|
167
|
+
s: (i.s + l * a) % e.length,
|
|
168
|
+
tangent: p,
|
|
169
|
+
lateral: m,
|
|
170
|
+
signedDistance: m,
|
|
171
|
+
segment: r
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
return n;
|
|
176
|
+
}
|
|
177
|
+
function y(e = "neon_city", t = 0, { speedClass: r } = {}) {
|
|
178
|
+
let i = e === "random" ? "neon_city" : e;
|
|
179
|
+
if (!l.includes(i)) throw RangeError(`Unsupported race map: ${e}`);
|
|
180
|
+
if (r != null && !c(r)) throw RangeError(`Unsupported speed class: ${r}`);
|
|
181
|
+
let a = h(t), o = c(r), s = o ? o.trackLength : n.trackLength, v = o ? o.trackWidth : n.trackWidth, y = Array.from({ length: u }, (e, t) => {
|
|
182
|
+
let n = t / u * Math.PI * 2;
|
|
183
|
+
return {
|
|
184
|
+
x: 110 * Math.cos(n),
|
|
185
|
+
z: 75 * Math.sin(n)
|
|
186
|
+
};
|
|
187
|
+
}), b = s / y.reduce((e, t, n) => e + p(t, y[(n + 1) % u]), 0), x = y.map((e) => ({
|
|
188
|
+
x: f(e.x * b),
|
|
189
|
+
z: f(e.z * b)
|
|
190
|
+
}));
|
|
191
|
+
x.push({ ...x[0] });
|
|
192
|
+
let S = 0;
|
|
193
|
+
x.forEach((e, t) => {
|
|
194
|
+
t && (S += p(x[t - 1], e)), e.s = S;
|
|
195
|
+
});
|
|
196
|
+
let C = [
|
|
197
|
+
0,
|
|
198
|
+
1,
|
|
199
|
+
2,
|
|
200
|
+
3
|
|
201
|
+
].map((e) => {
|
|
202
|
+
let t = e * u / 4, n = x[t], r = g(x, t), i = {
|
|
203
|
+
x: -r.z,
|
|
204
|
+
z: r.x
|
|
205
|
+
};
|
|
206
|
+
return {
|
|
207
|
+
id: e,
|
|
208
|
+
index: e,
|
|
209
|
+
s: n.s,
|
|
210
|
+
center: {
|
|
211
|
+
x: n.x,
|
|
212
|
+
z: n.z
|
|
213
|
+
},
|
|
214
|
+
normal: r,
|
|
215
|
+
halfWidth: v / 2,
|
|
216
|
+
a: {
|
|
217
|
+
x: n.x + i.x * v / 2,
|
|
218
|
+
z: n.z + i.z * v / 2
|
|
219
|
+
},
|
|
220
|
+
b: {
|
|
221
|
+
x: n.x - i.x * v / 2,
|
|
222
|
+
z: n.z - i.z * v / 2
|
|
223
|
+
}
|
|
224
|
+
};
|
|
225
|
+
}), w = [-1, 1].map((e) => ({
|
|
226
|
+
id: e < 0 ? "right_edge" : "left_edge",
|
|
227
|
+
type: "track_boundary",
|
|
228
|
+
points: x.map((t, n) => {
|
|
229
|
+
let r = g(x, n % u), i = v / 2 + d;
|
|
230
|
+
return {
|
|
231
|
+
x: f(t.x - r.z * e * i),
|
|
232
|
+
z: f(t.z + r.x * e * i)
|
|
233
|
+
};
|
|
234
|
+
})
|
|
235
|
+
})), T = {
|
|
236
|
+
mapId: i,
|
|
237
|
+
seed: a,
|
|
238
|
+
...o ? { speedClass: o.id } : {},
|
|
239
|
+
rulesVersion: 1,
|
|
240
|
+
width: v,
|
|
241
|
+
barrierMargin: d,
|
|
242
|
+
length: S,
|
|
243
|
+
points: x,
|
|
244
|
+
checkpoints: C,
|
|
245
|
+
colliders: w
|
|
246
|
+
}, E = _(T, S - 8), D = Math.atan2(E.tangent.x, E.tangent.z);
|
|
247
|
+
return T.grid = [-v / 4, v / 4].map((e, t) => ({
|
|
248
|
+
playerIndex: t,
|
|
249
|
+
x: E.x - E.tangent.z * e,
|
|
250
|
+
z: E.z + E.tangent.x * e,
|
|
251
|
+
s: E.s,
|
|
252
|
+
lateral: e,
|
|
253
|
+
yaw: D,
|
|
254
|
+
heading: D
|
|
255
|
+
})), T.startFinish = C[0], T.trackHash = `racing-v1-${m(JSON.stringify(T))}`, T;
|
|
256
|
+
}
|
|
257
|
+
export { o as a, n as i, v as n, c as o, t as r, y as t };
|
|
258
|
+
|
|
259
|
+
//# sourceMappingURL=track-BcnnpnAm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"track-BcnnpnAm.js","names":["RACE_CLASS_IDS","DEFAULT_RACE_CLASS","LEGACY_RACE","BASE","round","n","defineClass","top","topKmh","rules","acceleration","rollingDrag","RACE_CLASSES","isRaceClass","value","getRaceClass","RACE_TRACK_MAP_IDS","SEGMENTS","BARRIER_MARGIN","rounded","distanceBetween","b","a","hashText","hash","i","text","normalizeSeed","seed","tangentAt","previous","points","index","next","magnitude","sampleTrack","distance","s","track","segment","length","t","projectToTrack","position","best","dx","dz","lengthSquared","x","z","tangent","lateral","generateTrack","selectedMap","mapId","speedClass","normalizedSeed","raceClass","targetLength","roadWidth","raw","angle","scale","sum","point","checkpoints","pointIndex","normal","side","colliders","offset","start","yaw"],"sources":["../../src/games/racing-live/logic/classes.js","../../src/games/racing-live/logic/track.js"],"sourcesContent":["// Mario-Kart-style speed classes. Pure data: no imports so track.js and car.js can share it.\n// Top speed is the REAL equilibrium of stepCar at full throttle on tarmac:\n// acceleration = rollingDrag·v + airDrag·v² → airDrag = (acceleration − rollingDrag·v) / v²\n// maxSpeed is only a safety ceiling 5 % above that equilibrium.\nexport const RACE_CLASS_IDS = Object.freeze(['50cc', '100cc', '200cc', '400cc', '500cc']);\nexport const DEFAULT_RACE_CLASS = '200cc';\n// Invitations without speed_class keep the original rules, laps and 600 m circuit.\nexport const LEGACY_RACE = Object.freeze({ laps: 3, trackLength: 600, trackWidth: 10 });\n\nconst BASE = { reverseSpeed: 10, grassDrag: 4, barrierMargin: 3, barrierBounce: 0.22, steeringRate: 1.65 };\nconst round = (n) => Math.round(n * 1e7) / 1e7;\n\nfunction defineClass({ id, label, topKmh, laps, trackLength, trackWidth, acceleration, braking, rollingDrag, lateralGrip, driftGrip, steerFalloffSpeed }) {\n const top = topKmh / 3.6;\n const rules = Object.freeze({ ...BASE, maxSpeed: round(top * 1.05), acceleration, braking, rollingDrag,\n airDrag: round((acceleration - rollingDrag * top) / (top * top)), lateralGrip, driftGrip, steerFalloffSpeed });\n return Object.freeze({ id, label, topKmh, laps, trackLength, trackWidth, rules });\n}\n\nexport const RACE_CLASSES = Object.freeze({\n '50cc': defineClass({ id: '50cc', label: '50cc', topKmh: 80, laps: 3, trackLength: 600, trackWidth: 10,\n acceleration: 11, braking: 20, rollingDrag: 0.3, lateralGrip: 10, driftGrip: 2.5, steerFalloffSpeed: 40 }),\n '100cc': defineClass({ id: '100cc', label: '100cc', topKmh: 130, laps: 3, trackLength: 600, trackWidth: 10,\n acceleration: 15, braking: 26, rollingDrag: 0.3, lateralGrip: 11, driftGrip: 2.7, steerFalloffSpeed: 50 }),\n '200cc': defineClass({ id: '200cc', label: '200cc', topKmh: 200, laps: 3, trackLength: 1200, trackWidth: 12,\n acceleration: 21, braking: 34, rollingDrag: 0.3, lateralGrip: 13, driftGrip: 3, steerFalloffSpeed: 65 }),\n '400cc': defineClass({ id: '400cc', label: '400cc', topKmh: 300, laps: 3, trackLength: 2000, trackWidth: 14,\n acceleration: 29, braking: 45, rollingDrag: 0.3, lateralGrip: 15, driftGrip: 3.4, steerFalloffSpeed: 90 }),\n '500cc': defineClass({ id: '500cc', label: '500cc', topKmh: 380, laps: 4, trackLength: 2000, trackWidth: 14,\n acceleration: 35, braking: 52, rollingDrag: 0.3, lateralGrip: 16, driftGrip: 3.6, steerFalloffSpeed: 105 }),\n});\n\nexport const isRaceClass = (value) => typeof value === 'string' && RACE_CLASS_IDS.includes(value);\n/** Class definition or null for legacy invitations (no speed_class). */\nexport const getRaceClass = (value) => (isRaceClass(value) ? RACE_CLASSES[value] : null);\n","import { getRaceClass, LEGACY_RACE } from './classes.js';\n\n// MVP geometry in metres. The seed varies future scenery, never player advantages.\nexport const RACE_TRACK_RULES_VERSION = 1;\nexport const RACE_TRACK_MAP_IDS = Object.freeze(['neon_city']);\nconst SEGMENTS = 128;\nconst BARRIER_MARGIN = 3;\nconst rounded = (n) => Math.round(n * 1e6) / 1e6;\nconst distanceBetween = (a, b) => Math.hypot(b.x - a.x, b.z - a.z);\n\nfunction hashText(text) {\n let hash = 2166136261;\n for (let i = 0; i < text.length; i += 1) {\n hash ^= text.charCodeAt(i);\n hash = Math.imul(hash, 16777619);\n }\n return (hash >>> 0).toString(16).padStart(8, '0');\n}\n\nfunction normalizeSeed(seed) {\n if (typeof seed === 'string') return parseInt(hashText(seed), 16);\n if (typeof seed !== 'number' || !Number.isFinite(seed)) throw new TypeError('Race seed must be a finite number or string');\n return Math.trunc(seed) >>> 0;\n}\n\nfunction tangentAt(points, index) {\n const previous = points[(index + SEGMENTS - 1) % SEGMENTS];\n const next = points[(index + 1) % SEGMENTS];\n const magnitude = distanceBetween(previous, next);\n return { x: (next.x - previous.x) / magnitude, z: (next.z - previous.z) / magnitude };\n}\n\n/** Sample the closed polyline by travelled centre-line distance. */\nexport function sampleTrack(track, distance) {\n if (!Number.isFinite(distance)) throw new TypeError('Track distance must be finite');\n const s = ((distance % track.length) + track.length) % track.length;\n let segment = track.points.length - 2;\n for (let i = 0; i < track.points.length - 1; i += 1) {\n if (s < track.points[i + 1].s) { segment = i; break; }\n }\n const a = track.points[segment];\n const b = track.points[segment + 1];\n const length = b.s - a.s;\n const t = (s - a.s) / length;\n return { x: a.x + (b.x - a.x) * t, z: a.z + (b.z - a.z) * t, s, segment,\n tangent: { x: (b.x - a.x) / length, z: (b.z - a.z) / length } };\n}\n\n/** Nearest centre-line point; positive lateral distance is to the driver's left. */\nexport function projectToTrack(track, position) {\n if (!Number.isFinite(position?.x) || !Number.isFinite(position?.z)) throw new TypeError('Position must contain finite x and z');\n let best;\n for (let segment = 0; segment < track.points.length - 1; segment += 1) {\n const a = track.points[segment];\n const b = track.points[segment + 1];\n const dx = b.x - a.x;\n const dz = b.z - a.z;\n const lengthSquared = dx * dx + dz * dz;\n const t = Math.min(1, Math.max(0, ((position.x - a.x) * dx + (position.z - a.z) * dz) / lengthSquared));\n const x = a.x + dx * t;\n const z = a.z + dz * t;\n const distance = Math.hypot(position.x - x, position.z - z);\n if (!best || distance < best.distance) {\n const length = Math.sqrt(lengthSquared);\n const tangent = { x: dx / length, z: dz / length };\n const lateral = (position.x - x) * -tangent.z + (position.z - z) * tangent.x;\n best = { x, z, point: { x, z }, distance, s: (a.s + t * length) % track.length,\n tangent, lateral, signedDistance: lateral, segment };\n }\n }\n return best;\n}\n\nexport const projectOnTrack = projectToTrack;\n\n/** First verified layout only. Unsupported maps fail explicitly until implemented.\n * `speedClass` scales the same oval (longer, wider, gentler curves) for faster classes and\n * enters the hash, so both clients must agree on it. Without it the legacy 600 m track is kept.\n */\nexport function generateTrack(mapId = 'neon_city', seed = 0, { speedClass } = {}) {\n const selectedMap = mapId === 'random' ? 'neon_city' : mapId;\n if (!RACE_TRACK_MAP_IDS.includes(selectedMap)) throw new RangeError(`Unsupported race map: ${mapId}`);\n if (speedClass != null && !getRaceClass(speedClass)) throw new RangeError(`Unsupported speed class: ${speedClass}`);\n const normalizedSeed = normalizeSeed(seed);\n const raceClass = getRaceClass(speedClass);\n const targetLength = raceClass ? raceClass.trackLength : LEGACY_RACE.trackLength;\n const roadWidth = raceClass ? raceClass.trackWidth : LEGACY_RACE.trackWidth;\n const raw = Array.from({ length: SEGMENTS }, (_, i) => {\n const angle = i / SEGMENTS * Math.PI * 2;\n return { x: 110 * Math.cos(angle), z: 75 * Math.sin(angle) };\n });\n const rawLength = raw.reduce((sum, point, i) => sum + distanceBetween(point, raw[(i + 1) % SEGMENTS]), 0);\n const scale = targetLength / rawLength;\n const points = raw.map((point) => ({ x: rounded(point.x * scale), z: rounded(point.z * scale) }));\n points.push({ ...points[0] });\n let length = 0;\n points.forEach((point, i) => {\n if (i) length += distanceBetween(points[i - 1], point);\n point.s = length;\n });\n // Checkpoints cover only the road. The traversable shoulder does not grant\n // progress: a driver must pass the gate on the road rather than cut around it.\n const checkpoints = [0, 1, 2, 3].map((index) => {\n const pointIndex = index * SEGMENTS / 4;\n const point = points[pointIndex];\n const normal = tangentAt(points, pointIndex);\n const side = { x: -normal.z, z: normal.x };\n return { id: index, index, s: point.s, center: { x: point.x, z: point.z }, normal, halfWidth: roadWidth / 2,\n a: { x: point.x + side.x * roadWidth / 2, z: point.z + side.z * roadWidth / 2 },\n b: { x: point.x - side.x * roadWidth / 2, z: point.z - side.z * roadWidth / 2 } };\n });\n // Physical barriers leave a three-metre shoulder beyond each road edge. No scenery\n // colliders are present; presentation must keep decoration outside these edges.\n const colliders = [-1, 1].map((side) => ({\n id: side < 0 ? 'right_edge' : 'left_edge', type: 'track_boundary',\n points: points.map((point, i) => {\n const tangent = tangentAt(points, i % SEGMENTS);\n const offset = roadWidth / 2 + BARRIER_MARGIN;\n return { x: rounded(point.x - tangent.z * side * offset), z: rounded(point.z + tangent.x * side * offset) };\n }),\n }));\n const track = { mapId: selectedMap, seed: normalizedSeed, ...(raceClass ? { speedClass: raceClass.id } : {}), rulesVersion: RACE_TRACK_RULES_VERSION, width: roadWidth, barrierMargin: BARRIER_MARGIN, length, points, checkpoints, colliders };\n const start = sampleTrack(track, length - 8);\n const yaw = Math.atan2(start.tangent.x, start.tangent.z);\n track.grid = [-roadWidth / 4, roadWidth / 4].map((lateral, playerIndex) => ({\n playerIndex, x: start.x - start.tangent.z * lateral, z: start.z + start.tangent.x * lateral,\n s: start.s, lateral, yaw, heading: yaw,\n }));\n track.startFinish = checkpoints[0];\n // Include all competitive geometry, grid and normalized seed in the versioned hash.\n track.trackHash = `racing-v${RACE_TRACK_RULES_VERSION}-${hashText(JSON.stringify(track))}`;\n return track;\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { CanvasTexture as e, Color as t, LinearFilter as n, RepeatWrapping as r } from "three";
|
|
2
|
+
// src/games/tanks/scene/util.js
|
|
3
|
+
var i = (e) => new t(e).convertSRGBToLinear(), a = (e, t, n) => e < t ? t : e > n ? n : e, o = (e) => e < 0 ? 0 : e > 1 ? 1 : e, s = (e, t, n) => {
|
|
4
|
+
let r = o((n - e) / (t - e));
|
|
5
|
+
return r * r * (3 - 2 * r);
|
|
6
|
+
}, c = Math.PI / 180, l = (e, t) => 1 - Math.exp(-e * t), u = (e) => {
|
|
7
|
+
for (; e > Math.PI;) e -= Math.PI * 2;
|
|
8
|
+
for (; e < -Math.PI;) e += Math.PI * 2;
|
|
9
|
+
return e;
|
|
10
|
+
}, d = (e, t) => {
|
|
11
|
+
let n = Math.sin(e * 127.1 + t * 311.7) * 43758.5453;
|
|
12
|
+
return n - Math.floor(n);
|
|
13
|
+
};
|
|
14
|
+
function f(e) {
|
|
15
|
+
let t = e >>> 0 || 1;
|
|
16
|
+
return () => (t ^= t << 13, t ^= t >>> 17, t ^= t << 5, (t >>> 0) / 4294967296);
|
|
17
|
+
}
|
|
18
|
+
function p(e, t) {
|
|
19
|
+
let n = document.createElement("canvas");
|
|
20
|
+
return n.width = e, n.height = t, n;
|
|
21
|
+
}
|
|
22
|
+
function m(t, i = !1) {
|
|
23
|
+
let a = new e(t);
|
|
24
|
+
return a.minFilter = n, a.magFilter = n, a.generateMipmaps = !1, i && (a.wrapS = r, a.wrapT = r), a;
|
|
25
|
+
}
|
|
26
|
+
function h(e = 64) {
|
|
27
|
+
let t = p(e, e), n = t.getContext("2d"), r = e / 2, i = n.createRadialGradient(r, r, 0, r, r, r);
|
|
28
|
+
return i.addColorStop(0, "rgba(255,255,255,1)"), i.addColorStop(.18, "rgba(255,255,255,0.85)"), i.addColorStop(.45, "rgba(255,255,255,0.32)"), i.addColorStop(1, "rgba(255,255,255,0)"), n.fillStyle = i, n.fillRect(0, 0, e, e), m(t);
|
|
29
|
+
}
|
|
30
|
+
function g(e = 64) {
|
|
31
|
+
let t = p(e, e), n = t.getContext("2d"), r = e / 2, i = f(7);
|
|
32
|
+
for (let t = 0; t < 7; t++) {
|
|
33
|
+
let t = i() * Math.PI * 2, a = i() * r * .32, o = r + Math.cos(t) * a, s = r + Math.sin(t) * a, c = r * (.45 + i() * .25), l = n.createRadialGradient(o, s, 0, o, s, c);
|
|
34
|
+
l.addColorStop(0, "rgba(255,255,255,0.55)"), l.addColorStop(.6, "rgba(255,255,255,0.25)"), l.addColorStop(1, "rgba(255,255,255,0)"), n.fillStyle = l, n.fillRect(0, 0, e, e);
|
|
35
|
+
}
|
|
36
|
+
return m(t);
|
|
37
|
+
}
|
|
38
|
+
function _(e = 128) {
|
|
39
|
+
let t = p(e, e), n = t.getContext("2d"), r = e / 2, i = n.createRadialGradient(r, r, 0, r, r, r);
|
|
40
|
+
return i.addColorStop(0, "rgba(255,255,255,0)"), i.addColorStop(.62, "rgba(255,255,255,0)"), i.addColorStop(.8, "rgba(255,255,255,0.55)"), i.addColorStop(.9, "rgba(255,255,255,1)"), i.addColorStop(1, "rgba(255,255,255,0)"), n.fillStyle = i, n.fillRect(0, 0, e, e), m(t);
|
|
41
|
+
}
|
|
42
|
+
function v(e = 64) {
|
|
43
|
+
let t = p(e, e), n = t.getContext("2d"), r = e / 2, i = n.createRadialGradient(r, r, 0, r, r, r);
|
|
44
|
+
return i.addColorStop(0, "rgba(0,0,0,0.6)"), i.addColorStop(.55, "rgba(0,0,0,0.38)"), i.addColorStop(1, "rgba(0,0,0,0)"), n.fillStyle = i, n.fillRect(0, 0, e, e), m(t);
|
|
45
|
+
}
|
|
46
|
+
function y() {
|
|
47
|
+
let e = p(64, 32), t = e.getContext("2d");
|
|
48
|
+
t.fillStyle = "#3b3b3e", t.fillRect(0, 0, 64, 32);
|
|
49
|
+
for (let e = 0; e < 4; e++) {
|
|
50
|
+
let n = e * 16;
|
|
51
|
+
t.fillStyle = "#1b1b1d", t.fillRect(n, 0, 6, 32), t.fillStyle = "#5a5a5f", t.fillRect(n + 6, 0, 2, 32), t.fillStyle = "#2a2a2d", t.fillRect(n + 8, 13, 8, 6);
|
|
52
|
+
}
|
|
53
|
+
return t.fillStyle = "rgba(0,0,0,0.35)", t.fillRect(0, 0, 64, 3), t.fillRect(0, 29, 64, 3), m(e, !0);
|
|
54
|
+
}
|
|
55
|
+
export { l as a, i as c, g as d, s as f, o as i, _ as l, u as m, v as n, h as o, y as p, a as r, d as s, c as t, f as u };
|
|
56
|
+
|
|
57
|
+
//# sourceMappingURL=util-DwI9bfS7.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"util-DwI9bfS7.js","names":["lin","Color","hex","clamp","v","a","b","clamp01","smooth","t","x","e0","e1","DEG","dampK","rate","dt","wrapPi","hash2","s","y","rng","seed","canvas","c","w","h","tex","CanvasTexture","LinearFilter","repeat","RepeatWrapping","glowTexture","size","g","grd","smokeTexture","rand","i","d","rr","ringTexture","blobTexture","trackTexture"],"sources":["../../src/games/tanks/scene/util.js"],"sourcesContent":["// Shared helpers for the tanks scene (pure, no per-frame allocations).\nimport { CanvasTexture, Color, LinearFilter, RepeatWrapping } from 'three'\n\nexport const lin = (hex) => new Color(hex).convertSRGBToLinear()\nexport const clamp = (v, a, b) => (v < a ? a : v > b ? b : v)\nexport const clamp01 = (v) => (v < 0 ? 0 : v > 1 ? 1 : v)\nexport const lerp = (a, b, t) => a + (b - a) * t\nexport const smooth = (e0, e1, x) => {\n const t = clamp01((x - e0) / (e1 - e0))\n return t * t * (3 - 2 * t)\n}\nexport const DEG = Math.PI / 180\n// exponential damping factor for frame-rate independent smoothing\nexport const dampK = (rate, dt) => 1 - Math.exp(-rate * dt)\nexport const wrapPi = (a) => {\n while (a > Math.PI) a -= Math.PI * 2\n while (a < -Math.PI) a += Math.PI * 2\n return a\n}\n// deterministic hash in [0,1)\nexport const hash2 = (x, y) => {\n const s = Math.sin(x * 127.1 + y * 311.7) * 43758.5453\n return s - Math.floor(s)\n}\n\n// Tiny seeded PRNG for decor jitter (stable across rebuilds).\nexport function rng(seed) {\n let s = seed >>> 0 || 1\n return () => {\n s ^= s << 13\n s ^= s >>> 17\n s ^= s << 5\n return (s >>> 0) / 4294967296\n }\n}\n\nfunction canvas(w, h) {\n const c = document.createElement('canvas')\n c.width = w\n c.height = h\n return c\n}\n\nfunction tex(c, repeat = false) {\n const t = new CanvasTexture(c)\n t.minFilter = LinearFilter\n t.magFilter = LinearFilter\n t.generateMipmaps = false\n if (repeat) {\n t.wrapS = RepeatWrapping\n t.wrapT = RepeatWrapping\n }\n return t\n}\n\n// Soft radial glow (white, alpha falloff) for additive sprites/points.\nexport function glowTexture(size = 64) {\n const c = canvas(size, size)\n const g = c.getContext('2d')\n const r = size / 2\n const grd = g.createRadialGradient(r, r, 0, r, r, r)\n grd.addColorStop(0, 'rgba(255,255,255,1)')\n grd.addColorStop(0.18, 'rgba(255,255,255,0.85)')\n grd.addColorStop(0.45, 'rgba(255,255,255,0.32)')\n grd.addColorStop(1, 'rgba(255,255,255,0)')\n g.fillStyle = grd\n g.fillRect(0, 0, size, size)\n return tex(c)\n}\n\n// Puffy smoke blob: several overlapping soft circles (alpha only).\nexport function smokeTexture(size = 64) {\n const c = canvas(size, size)\n const g = c.getContext('2d')\n const r = size / 2\n const rand = rng(7)\n for (let i = 0; i < 7; i++) {\n const a = rand() * Math.PI * 2\n const d = rand() * r * 0.32\n const x = r + Math.cos(a) * d\n const y = r + Math.sin(a) * d\n const rr = r * (0.45 + rand() * 0.25)\n const grd = g.createRadialGradient(x, y, 0, x, y, rr)\n grd.addColorStop(0, 'rgba(255,255,255,0.55)')\n grd.addColorStop(0.6, 'rgba(255,255,255,0.25)')\n grd.addColorStop(1, 'rgba(255,255,255,0)')\n g.fillStyle = grd\n g.fillRect(0, 0, size, size)\n }\n return tex(c)\n}\n\n// Thin bright ring for shockwaves / target markers.\nexport function ringTexture(size = 128) {\n const c = canvas(size, size)\n const g = c.getContext('2d')\n const r = size / 2\n const grd = g.createRadialGradient(r, r, 0, r, r, r)\n grd.addColorStop(0, 'rgba(255,255,255,0)')\n grd.addColorStop(0.62, 'rgba(255,255,255,0)')\n grd.addColorStop(0.8, 'rgba(255,255,255,0.55)')\n grd.addColorStop(0.9, 'rgba(255,255,255,1)')\n grd.addColorStop(1, 'rgba(255,255,255,0)')\n g.fillStyle = grd\n g.fillRect(0, 0, size, size)\n return tex(c)\n}\n\n// Blob shadow (dark center, soft edge).\nexport function blobTexture(size = 64) {\n const c = canvas(size, size)\n const g = c.getContext('2d')\n const r = size / 2\n const grd = g.createRadialGradient(r, r, 0, r, r, r)\n grd.addColorStop(0, 'rgba(0,0,0,0.6)')\n grd.addColorStop(0.55, 'rgba(0,0,0,0.38)')\n grd.addColorStop(1, 'rgba(0,0,0,0)')\n g.fillStyle = grd\n g.fillRect(0, 0, size, size)\n return tex(c)\n}\n\n// Track tread strip: u runs along the track loop, v across its width.\nexport function trackTexture() {\n const c = canvas(64, 32)\n const g = c.getContext('2d')\n g.fillStyle = '#3b3b3e'\n g.fillRect(0, 0, 64, 32)\n for (let i = 0; i < 4; i++) {\n const x = i * 16\n g.fillStyle = '#1b1b1d'\n g.fillRect(x, 0, 6, 32)\n g.fillStyle = '#5a5a5f'\n g.fillRect(x + 6, 0, 2, 32)\n g.fillStyle = '#2a2a2d'\n g.fillRect(x + 8, 13, 8, 6)\n }\n g.fillStyle = 'rgba(0,0,0,0.35)'\n g.fillRect(0, 0, 64, 3)\n g.fillRect(0, 29, 64, 3)\n return tex(c, true)\n}\n"],"mappings":"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"}
|