@almadar/ui 5.85.0 → 5.87.0
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/dist/avl/index.cjs +139 -1415
- package/dist/avl/index.js +139 -1415
- package/dist/components/game/2d/molecules/index.d.ts +0 -2
- package/dist/components/game/shared/index.d.ts +0 -2
- package/dist/components/index.cjs +124 -1478
- package/dist/components/index.js +125 -1468
- package/dist/providers/index.cjs +109 -1385
- package/dist/providers/index.js +109 -1385
- package/dist/runtime/index.cjs +115 -1391
- package/dist/runtime/index.js +115 -1391
- package/package.json +1 -1
- package/dist/components/game/2d/organisms/CanvasEffect.d.ts +0 -70
- package/dist/components/game/shared/canvasEffects.d.ts +0 -50
- package/dist/components/game/shared/combatPresets.d.ts +0 -15
- package/dist/components/game/shared/hooks/useCanvasEffects.d.ts +0 -27
package/dist/components/index.js
CHANGED
|
@@ -1224,12 +1224,12 @@ function kebabToPascal(name) {
|
|
|
1224
1224
|
}).join("");
|
|
1225
1225
|
}
|
|
1226
1226
|
function loadLib(key, importer) {
|
|
1227
|
-
let
|
|
1228
|
-
if (!
|
|
1229
|
-
|
|
1230
|
-
libPromises.set(key,
|
|
1227
|
+
let p = libPromises.get(key);
|
|
1228
|
+
if (!p) {
|
|
1229
|
+
p = importer();
|
|
1230
|
+
libPromises.set(key, p);
|
|
1231
1231
|
}
|
|
1232
|
-
return
|
|
1232
|
+
return p;
|
|
1233
1233
|
}
|
|
1234
1234
|
function lazyFamilyIcon(libKey, importer, pick, fallbackName, family) {
|
|
1235
1235
|
const Lazy = React74__default.lazy(async () => {
|
|
@@ -5327,28 +5327,28 @@ var init_ConfettiEffect = __esm({
|
|
|
5327
5327
|
),
|
|
5328
5328
|
"aria-hidden": "true",
|
|
5329
5329
|
children: [
|
|
5330
|
-
particles.map((
|
|
5331
|
-
const rad =
|
|
5332
|
-
const tx = Math.cos(rad) *
|
|
5333
|
-
const ty = Math.sin(rad) *
|
|
5330
|
+
particles.map((p) => {
|
|
5331
|
+
const rad = p.angle * Math.PI / 180;
|
|
5332
|
+
const tx = Math.cos(rad) * p.distance;
|
|
5333
|
+
const ty = Math.sin(rad) * p.distance - 20;
|
|
5334
5334
|
return /* @__PURE__ */ jsx(
|
|
5335
5335
|
Box,
|
|
5336
5336
|
{
|
|
5337
5337
|
className: "absolute rounded-sm",
|
|
5338
5338
|
style: {
|
|
5339
|
-
left: `${
|
|
5339
|
+
left: `${p.left}%`,
|
|
5340
5340
|
top: "50%",
|
|
5341
|
-
width:
|
|
5342
|
-
height:
|
|
5343
|
-
backgroundColor:
|
|
5344
|
-
animation: `confetti-burst ${duration -
|
|
5341
|
+
width: p.size,
|
|
5342
|
+
height: p.size,
|
|
5343
|
+
backgroundColor: p.color,
|
|
5344
|
+
animation: `confetti-burst ${duration - p.delay}ms ease-out ${p.delay}ms forwards`,
|
|
5345
5345
|
opacity: 0,
|
|
5346
5346
|
"--confetti-tx": `${tx}px`,
|
|
5347
5347
|
"--confetti-ty": `${ty}px`,
|
|
5348
|
-
"--confetti-rotate": `${
|
|
5348
|
+
"--confetti-rotate": `${p.rotation}deg`
|
|
5349
5349
|
}
|
|
5350
5350
|
},
|
|
5351
|
-
|
|
5351
|
+
p.id
|
|
5352
5352
|
);
|
|
5353
5353
|
}),
|
|
5354
5354
|
/* @__PURE__ */ jsx("style", { children: `
|
|
@@ -6259,8 +6259,8 @@ var init_AnimatedGraphic = __esm({
|
|
|
6259
6259
|
const el = containerRef.current;
|
|
6260
6260
|
if (!el || !strokeColor) return;
|
|
6261
6261
|
const paths = el.querySelectorAll("path, line, polyline, polygon, circle, ellipse, rect");
|
|
6262
|
-
paths.forEach((
|
|
6263
|
-
|
|
6262
|
+
paths.forEach((p) => {
|
|
6263
|
+
p.style.stroke = strokeColor;
|
|
6264
6264
|
});
|
|
6265
6265
|
}, [resolvedSvg, strokeColor]);
|
|
6266
6266
|
useEffect(() => {
|
|
@@ -6268,23 +6268,23 @@ var init_AnimatedGraphic = __esm({
|
|
|
6268
6268
|
if (!el || !resolvedSvg) return;
|
|
6269
6269
|
if (animation === "draw" || animation === "fill") {
|
|
6270
6270
|
const paths = el.querySelectorAll("path, line, polyline, polygon, circle, ellipse, rect");
|
|
6271
|
-
paths.forEach((
|
|
6272
|
-
if ("getTotalLength" in
|
|
6273
|
-
const len =
|
|
6274
|
-
|
|
6275
|
-
|
|
6271
|
+
paths.forEach((p) => {
|
|
6272
|
+
if ("getTotalLength" in p && typeof p.getTotalLength === "function") {
|
|
6273
|
+
const len = p.getTotalLength();
|
|
6274
|
+
p.style.strokeDasharray = `${len}`;
|
|
6275
|
+
p.style.strokeDashoffset = `${len}`;
|
|
6276
6276
|
}
|
|
6277
6277
|
if (animation === "fill") {
|
|
6278
|
-
|
|
6278
|
+
p.style.fillOpacity = "0";
|
|
6279
6279
|
}
|
|
6280
6280
|
});
|
|
6281
6281
|
}
|
|
6282
6282
|
if (animation === "morph") {
|
|
6283
6283
|
const paths = el.querySelectorAll("path, circle, ellipse, rect, polygon");
|
|
6284
|
-
paths.forEach((
|
|
6285
|
-
|
|
6286
|
-
|
|
6287
|
-
|
|
6284
|
+
paths.forEach((p) => {
|
|
6285
|
+
p.style.transform = "scale(0)";
|
|
6286
|
+
p.style.transformOrigin = "center";
|
|
6287
|
+
p.style.opacity = "0";
|
|
6288
6288
|
});
|
|
6289
6289
|
}
|
|
6290
6290
|
}, [resolvedSvg, animation]);
|
|
@@ -9554,8 +9554,8 @@ function shapeBounds(shape) {
|
|
|
9554
9554
|
case "polygon":
|
|
9555
9555
|
if (!shape.points || shape.points.length === 0) return null;
|
|
9556
9556
|
{
|
|
9557
|
-
const xs = shape.points.map((
|
|
9558
|
-
const ys = shape.points.map((
|
|
9557
|
+
const xs = shape.points.map((p) => p.x);
|
|
9558
|
+
const ys = shape.points.map((p) => p.y);
|
|
9559
9559
|
const minX = Math.min(...xs);
|
|
9560
9560
|
const minY = Math.min(...ys);
|
|
9561
9561
|
return {
|
|
@@ -9681,13 +9681,13 @@ function drawShape(ctx, shape, width, height) {
|
|
|
9681
9681
|
}
|
|
9682
9682
|
case "path": {
|
|
9683
9683
|
if (!shape.path) break;
|
|
9684
|
-
const
|
|
9684
|
+
const p = new Path2D(shape.path);
|
|
9685
9685
|
if (fill) {
|
|
9686
9686
|
ctx.fillStyle = fill;
|
|
9687
|
-
ctx.fill(
|
|
9687
|
+
ctx.fill(p);
|
|
9688
9688
|
}
|
|
9689
9689
|
ctx.strokeStyle = stroke;
|
|
9690
|
-
ctx.stroke(
|
|
9690
|
+
ctx.stroke(p);
|
|
9691
9691
|
break;
|
|
9692
9692
|
}
|
|
9693
9693
|
case "text": {
|
|
@@ -12744,7 +12744,7 @@ function renderStateMachineToDomData(stateMachine, options = {}, config = DEFAUL
|
|
|
12744
12744
|
}
|
|
12745
12745
|
let domOutputs;
|
|
12746
12746
|
if (outputs.length > 0) {
|
|
12747
|
-
const maxX = Math.max(...Object.values(positions).map((
|
|
12747
|
+
const maxX = Math.max(...Object.values(positions).map((p) => p.x));
|
|
12748
12748
|
const maxOutputLength = Math.max(...outputs.map((o) => o.length));
|
|
12749
12749
|
const boxWidth = Math.max(200, maxOutputLength * 7 + 30);
|
|
12750
12750
|
const lineHeight = 22;
|
|
@@ -13726,7 +13726,7 @@ var init_BookViewer = __esm({
|
|
|
13726
13726
|
}
|
|
13727
13727
|
});
|
|
13728
13728
|
function BoxPattern({
|
|
13729
|
-
p
|
|
13729
|
+
p,
|
|
13730
13730
|
m,
|
|
13731
13731
|
bg = "transparent",
|
|
13732
13732
|
border = false,
|
|
@@ -13739,7 +13739,7 @@ function BoxPattern({
|
|
|
13739
13739
|
return /* @__PURE__ */ jsx(
|
|
13740
13740
|
Box,
|
|
13741
13741
|
{
|
|
13742
|
-
padding:
|
|
13742
|
+
padding: p,
|
|
13743
13743
|
margin: m,
|
|
13744
13744
|
bg,
|
|
13745
13745
|
border,
|
|
@@ -15654,13 +15654,13 @@ function useRenderInterpolation(options = {}) {
|
|
|
15654
15654
|
const prevMap = /* @__PURE__ */ new Map();
|
|
15655
15655
|
for (const e of prev.entities) prevMap.set(e.id, e);
|
|
15656
15656
|
for (const c of curr.entities) {
|
|
15657
|
-
const
|
|
15658
|
-
if (!
|
|
15657
|
+
const p = prevMap.get(c.id);
|
|
15658
|
+
if (!p) {
|
|
15659
15659
|
out.set(c.id, { x: c.x, y: c.y });
|
|
15660
15660
|
} else {
|
|
15661
15661
|
out.set(c.id, {
|
|
15662
|
-
x:
|
|
15663
|
-
y:
|
|
15662
|
+
x: p.x + (c.x - p.x) * alpha,
|
|
15663
|
+
y: p.y + (c.y - p.y) * alpha
|
|
15664
15664
|
});
|
|
15665
15665
|
}
|
|
15666
15666
|
}
|
|
@@ -16409,8 +16409,8 @@ function Canvas2D({
|
|
|
16409
16409
|
if (isFree) return 0;
|
|
16410
16410
|
return (gridHeight - 1) * (scaledTileWidth / 2);
|
|
16411
16411
|
}, [isFree, gridHeight, scaledTileWidth]);
|
|
16412
|
-
const validMoveSet = useMemo(() => new Set(validMoves.map((
|
|
16413
|
-
const attackTargetSet = useMemo(() => new Set(attackTargets.map((
|
|
16412
|
+
const validMoveSet = useMemo(() => new Set(validMoves.map((p) => `${p.x},${p.y}`)), [validMoves]);
|
|
16413
|
+
const attackTargetSet = useMemo(() => new Set(attackTargets.map((p) => `${p.x},${p.y}`)), [attackTargets]);
|
|
16414
16414
|
const spriteUrls = useMemo(() => {
|
|
16415
16415
|
const urls = [];
|
|
16416
16416
|
for (const tile of sortedTiles) {
|
|
@@ -17128,1278 +17128,6 @@ var init_Canvas2D = __esm({
|
|
|
17128
17128
|
}
|
|
17129
17129
|
});
|
|
17130
17130
|
|
|
17131
|
-
// components/game/shared/effects.ts
|
|
17132
|
-
var EMPTY_EFFECT_STATE;
|
|
17133
|
-
var init_effects = __esm({
|
|
17134
|
-
"components/game/shared/effects.ts"() {
|
|
17135
|
-
EMPTY_EFFECT_STATE = {
|
|
17136
|
-
particles: [],
|
|
17137
|
-
sequences: [],
|
|
17138
|
-
overlays: []
|
|
17139
|
-
};
|
|
17140
|
-
}
|
|
17141
|
-
});
|
|
17142
|
-
|
|
17143
|
-
// components/game/shared/canvasEffects.ts
|
|
17144
|
-
function getOffscreenCtx(w, h) {
|
|
17145
|
-
if (!_offscreen) {
|
|
17146
|
-
if (typeof OffscreenCanvas !== "undefined") {
|
|
17147
|
-
_offscreen = new OffscreenCanvas(w, h);
|
|
17148
|
-
} else {
|
|
17149
|
-
_offscreen = document.createElement("canvas");
|
|
17150
|
-
}
|
|
17151
|
-
}
|
|
17152
|
-
if (_offscreen.width < w) _offscreen.width = w;
|
|
17153
|
-
if (_offscreen.height < h) _offscreen.height = h;
|
|
17154
|
-
if (!_offCtx) {
|
|
17155
|
-
_offCtx = _offscreen.getContext("2d");
|
|
17156
|
-
}
|
|
17157
|
-
return _offCtx;
|
|
17158
|
-
}
|
|
17159
|
-
function drawTintedImage(ctx, img, x, y, w, h, tint, alpha, blendMode = "source-over") {
|
|
17160
|
-
if (w <= 0 || h <= 0) return;
|
|
17161
|
-
const oc = getOffscreenCtx(w, h);
|
|
17162
|
-
oc.clearRect(0, 0, w, h);
|
|
17163
|
-
oc.globalCompositeOperation = "source-over";
|
|
17164
|
-
oc.drawImage(img, 0, 0, w, h);
|
|
17165
|
-
oc.globalCompositeOperation = "source-atop";
|
|
17166
|
-
oc.fillStyle = `rgb(${tint.r}, ${tint.g}, ${tint.b})`;
|
|
17167
|
-
oc.fillRect(0, 0, w, h);
|
|
17168
|
-
const prevAlpha = ctx.globalAlpha;
|
|
17169
|
-
const prevBlend = ctx.globalCompositeOperation;
|
|
17170
|
-
ctx.globalAlpha = alpha;
|
|
17171
|
-
ctx.globalCompositeOperation = blendMode;
|
|
17172
|
-
ctx.drawImage(_offscreen, 0, 0, w, h, x, y, w, h);
|
|
17173
|
-
ctx.globalAlpha = prevAlpha;
|
|
17174
|
-
ctx.globalCompositeOperation = prevBlend;
|
|
17175
|
-
}
|
|
17176
|
-
function randRange(min, max) {
|
|
17177
|
-
return min + Math.random() * (max - min);
|
|
17178
|
-
}
|
|
17179
|
-
function spawnParticles(config, animTime) {
|
|
17180
|
-
const particles = [];
|
|
17181
|
-
for (let i = 0; i < config.count; i++) {
|
|
17182
|
-
const angle = randRange(config.angleMin, config.angleMax);
|
|
17183
|
-
const speed = randRange(config.velocityMin, config.velocityMax);
|
|
17184
|
-
const spriteUrl = config.spriteUrls[Math.floor(Math.random() * config.spriteUrls.length)];
|
|
17185
|
-
particles.push({
|
|
17186
|
-
spriteUrl,
|
|
17187
|
-
x: config.originX + randRange(-config.spread, config.spread),
|
|
17188
|
-
y: config.originY + randRange(-config.spread, config.spread),
|
|
17189
|
-
vx: Math.cos(angle) * speed,
|
|
17190
|
-
vy: Math.sin(angle) * speed,
|
|
17191
|
-
gravity: config.gravity,
|
|
17192
|
-
rotation: Math.random() * Math.PI * 2,
|
|
17193
|
-
rotationSpeed: randRange(config.rotationSpeedMin ?? -2, config.rotationSpeedMax ?? 2),
|
|
17194
|
-
scale: randRange(config.scaleMin, config.scaleMax),
|
|
17195
|
-
scaleSpeed: config.scaleSpeed ?? 0,
|
|
17196
|
-
alpha: config.alpha ?? 1,
|
|
17197
|
-
fadeRate: config.fadeRate ?? -1.5,
|
|
17198
|
-
tint: { ...config.tint },
|
|
17199
|
-
blendMode: config.blendMode ?? "source-over",
|
|
17200
|
-
spawnTime: animTime,
|
|
17201
|
-
lifetime: randRange(config.lifetimeMin, config.lifetimeMax)
|
|
17202
|
-
});
|
|
17203
|
-
}
|
|
17204
|
-
return particles;
|
|
17205
|
-
}
|
|
17206
|
-
function spawnSequence(config, animTime) {
|
|
17207
|
-
return {
|
|
17208
|
-
frameUrls: config.frameUrls,
|
|
17209
|
-
x: config.originX,
|
|
17210
|
-
y: config.originY,
|
|
17211
|
-
frameDuration: config.frameDuration,
|
|
17212
|
-
startTime: animTime,
|
|
17213
|
-
loop: config.loop ?? false,
|
|
17214
|
-
scale: config.scale ?? 1,
|
|
17215
|
-
tint: config.tint ?? null,
|
|
17216
|
-
alpha: config.alpha ?? 1,
|
|
17217
|
-
blendMode: config.blendMode ?? "source-over"
|
|
17218
|
-
};
|
|
17219
|
-
}
|
|
17220
|
-
function spawnOverlay(config, animTime) {
|
|
17221
|
-
return {
|
|
17222
|
-
spriteUrl: config.spriteUrl,
|
|
17223
|
-
x: config.originX,
|
|
17224
|
-
y: config.originY,
|
|
17225
|
-
alpha: config.alpha ?? 0.8,
|
|
17226
|
-
fadeRate: config.fadeRate ?? -0.5,
|
|
17227
|
-
pulseAmplitude: config.pulseAmplitude ?? 0,
|
|
17228
|
-
pulseFrequency: config.pulseFrequency ?? 2,
|
|
17229
|
-
scale: config.scale ?? 1,
|
|
17230
|
-
blendMode: config.blendMode ?? "source-over",
|
|
17231
|
-
spawnTime: animTime,
|
|
17232
|
-
lifetime: config.lifetime ?? 2e3
|
|
17233
|
-
};
|
|
17234
|
-
}
|
|
17235
|
-
function updateEffectState(state, animTime, deltaMs) {
|
|
17236
|
-
const dt = deltaMs / 1e3;
|
|
17237
|
-
const particles = state.particles.map((p2) => ({
|
|
17238
|
-
...p2,
|
|
17239
|
-
x: p2.x + p2.vx * dt,
|
|
17240
|
-
y: p2.y + p2.vy * dt,
|
|
17241
|
-
vy: p2.vy + p2.gravity * dt,
|
|
17242
|
-
rotation: p2.rotation + p2.rotationSpeed * dt,
|
|
17243
|
-
scale: Math.max(0, p2.scale + p2.scaleSpeed * dt),
|
|
17244
|
-
alpha: Math.max(0, p2.alpha + p2.fadeRate * dt)
|
|
17245
|
-
})).filter((p2) => p2.alpha > 0.01 && animTime - p2.spawnTime < p2.lifetime);
|
|
17246
|
-
const sequences = state.sequences.filter((s) => {
|
|
17247
|
-
const elapsed = animTime - s.startTime;
|
|
17248
|
-
const totalDuration = s.frameUrls.length * s.frameDuration;
|
|
17249
|
-
return s.loop || elapsed < totalDuration;
|
|
17250
|
-
});
|
|
17251
|
-
const overlays = state.overlays.map((o) => ({
|
|
17252
|
-
...o,
|
|
17253
|
-
alpha: Math.max(0, o.alpha + o.fadeRate * dt)
|
|
17254
|
-
})).filter((o) => o.alpha > 0.01 && animTime - o.spawnTime < o.lifetime);
|
|
17255
|
-
return { particles, sequences, overlays };
|
|
17256
|
-
}
|
|
17257
|
-
function drawEffectState(ctx, state, animTime, getImage) {
|
|
17258
|
-
for (const o of state.overlays) {
|
|
17259
|
-
const img = getImage(o.spriteUrl);
|
|
17260
|
-
if (!img) continue;
|
|
17261
|
-
let alpha = o.alpha;
|
|
17262
|
-
if (o.pulseAmplitude > 0) {
|
|
17263
|
-
const elapsed = (animTime - o.spawnTime) / 1e3;
|
|
17264
|
-
alpha += Math.sin(elapsed * o.pulseFrequency * Math.PI * 2) * o.pulseAmplitude;
|
|
17265
|
-
alpha = Math.max(0, Math.min(1, alpha));
|
|
17266
|
-
}
|
|
17267
|
-
const w = img.naturalWidth * o.scale;
|
|
17268
|
-
const h = img.naturalHeight * o.scale;
|
|
17269
|
-
const prevAlpha = ctx.globalAlpha;
|
|
17270
|
-
const prevBlend = ctx.globalCompositeOperation;
|
|
17271
|
-
ctx.globalAlpha = alpha;
|
|
17272
|
-
ctx.globalCompositeOperation = o.blendMode;
|
|
17273
|
-
ctx.drawImage(img, o.x - w / 2, o.y - h / 2, w, h);
|
|
17274
|
-
ctx.globalAlpha = prevAlpha;
|
|
17275
|
-
ctx.globalCompositeOperation = prevBlend;
|
|
17276
|
-
}
|
|
17277
|
-
for (const s of state.sequences) {
|
|
17278
|
-
const elapsed = animTime - s.startTime;
|
|
17279
|
-
let frameIndex = Math.floor(elapsed / s.frameDuration);
|
|
17280
|
-
if (s.loop) {
|
|
17281
|
-
frameIndex = frameIndex % s.frameUrls.length;
|
|
17282
|
-
} else if (frameIndex >= s.frameUrls.length) {
|
|
17283
|
-
continue;
|
|
17284
|
-
}
|
|
17285
|
-
const img = getImage(s.frameUrls[frameIndex]);
|
|
17286
|
-
if (!img) continue;
|
|
17287
|
-
const w = img.naturalWidth * s.scale;
|
|
17288
|
-
const h = img.naturalHeight * s.scale;
|
|
17289
|
-
if (s.tint) {
|
|
17290
|
-
drawTintedImage(ctx, img, s.x - w / 2, s.y - h / 2, w, h, s.tint, s.alpha, s.blendMode);
|
|
17291
|
-
} else {
|
|
17292
|
-
const prevAlpha = ctx.globalAlpha;
|
|
17293
|
-
const prevBlend = ctx.globalCompositeOperation;
|
|
17294
|
-
ctx.globalAlpha = s.alpha;
|
|
17295
|
-
ctx.globalCompositeOperation = s.blendMode;
|
|
17296
|
-
ctx.drawImage(img, s.x - w / 2, s.y - h / 2, w, h);
|
|
17297
|
-
ctx.globalAlpha = prevAlpha;
|
|
17298
|
-
ctx.globalCompositeOperation = prevBlend;
|
|
17299
|
-
}
|
|
17300
|
-
}
|
|
17301
|
-
for (const p2 of state.particles) {
|
|
17302
|
-
const img = getImage(p2.spriteUrl);
|
|
17303
|
-
if (!img) continue;
|
|
17304
|
-
const w = img.naturalWidth * p2.scale;
|
|
17305
|
-
const h = img.naturalHeight * p2.scale;
|
|
17306
|
-
ctx.save();
|
|
17307
|
-
ctx.translate(p2.x, p2.y);
|
|
17308
|
-
ctx.rotate(p2.rotation);
|
|
17309
|
-
drawTintedImage(ctx, img, -w / 2, -h / 2, w, h, p2.tint, p2.alpha, p2.blendMode);
|
|
17310
|
-
ctx.restore();
|
|
17311
|
-
}
|
|
17312
|
-
}
|
|
17313
|
-
function hasActiveEffects(state) {
|
|
17314
|
-
return state.particles.length > 0 || state.sequences.length > 0 || state.overlays.length > 0;
|
|
17315
|
-
}
|
|
17316
|
-
function getAllEffectSpriteUrls(manifest) {
|
|
17317
|
-
const urls = [];
|
|
17318
|
-
const base = manifest.baseUrl;
|
|
17319
|
-
if (manifest.particles) {
|
|
17320
|
-
for (const value of Object.values(manifest.particles)) {
|
|
17321
|
-
if (Array.isArray(value)) {
|
|
17322
|
-
value.forEach((v) => urls.push(`${base}/${v}`));
|
|
17323
|
-
} else if (typeof value === "string") {
|
|
17324
|
-
urls.push(`${base}/${value}`);
|
|
17325
|
-
}
|
|
17326
|
-
}
|
|
17327
|
-
}
|
|
17328
|
-
if (manifest.animations) {
|
|
17329
|
-
for (const frames of Object.values(manifest.animations)) {
|
|
17330
|
-
if (Array.isArray(frames)) {
|
|
17331
|
-
frames.forEach((f3) => urls.push(`${base}/${f3}`));
|
|
17332
|
-
}
|
|
17333
|
-
}
|
|
17334
|
-
}
|
|
17335
|
-
return urls;
|
|
17336
|
-
}
|
|
17337
|
-
var _offscreen, _offCtx;
|
|
17338
|
-
var init_canvasEffects = __esm({
|
|
17339
|
-
"components/game/shared/canvasEffects.ts"() {
|
|
17340
|
-
_offscreen = null;
|
|
17341
|
-
_offCtx = null;
|
|
17342
|
-
}
|
|
17343
|
-
});
|
|
17344
|
-
|
|
17345
|
-
// components/game/shared/combatPresets.ts
|
|
17346
|
-
function p(manifest, key) {
|
|
17347
|
-
const particles = manifest.particles;
|
|
17348
|
-
if (!particles) return [];
|
|
17349
|
-
const val = particles[key];
|
|
17350
|
-
if (Array.isArray(val)) return val.map((v) => `${manifest.baseUrl}/${v}`);
|
|
17351
|
-
if (typeof val === "string") return [`${manifest.baseUrl}/${val}`];
|
|
17352
|
-
return [];
|
|
17353
|
-
}
|
|
17354
|
-
function anim(manifest, key) {
|
|
17355
|
-
const animations = manifest.animations;
|
|
17356
|
-
if (!animations) return [];
|
|
17357
|
-
const val = animations[key];
|
|
17358
|
-
if (Array.isArray(val)) return val.map((v) => `${manifest.baseUrl}/${v}`);
|
|
17359
|
-
return [];
|
|
17360
|
-
}
|
|
17361
|
-
function createCombatPresets(manifest) {
|
|
17362
|
-
return {
|
|
17363
|
-
// =====================================================================
|
|
17364
|
-
// MELEE — slash (red) + dirt + scratch + flash sequence
|
|
17365
|
-
// =====================================================================
|
|
17366
|
-
melee: (originX, originY) => {
|
|
17367
|
-
const particles = [
|
|
17368
|
-
{
|
|
17369
|
-
spriteUrls: p(manifest, "slash"),
|
|
17370
|
-
count: 6,
|
|
17371
|
-
originX,
|
|
17372
|
-
originY,
|
|
17373
|
-
spread: 8,
|
|
17374
|
-
velocityMin: 40,
|
|
17375
|
-
velocityMax: 120,
|
|
17376
|
-
angleMin: -PI2 * 0.8,
|
|
17377
|
-
angleMax: -PI2 * 0.2,
|
|
17378
|
-
gravity: 0,
|
|
17379
|
-
tint: { r: 255, g: 60, b: 40 },
|
|
17380
|
-
scaleMin: 0.3,
|
|
17381
|
-
scaleMax: 0.6,
|
|
17382
|
-
lifetimeMin: 300,
|
|
17383
|
-
lifetimeMax: 500,
|
|
17384
|
-
fadeRate: -2.5
|
|
17385
|
-
},
|
|
17386
|
-
{
|
|
17387
|
-
spriteUrls: p(manifest, "dirt"),
|
|
17388
|
-
count: 4,
|
|
17389
|
-
originX,
|
|
17390
|
-
originY: originY + 10,
|
|
17391
|
-
spread: 12,
|
|
17392
|
-
velocityMin: 20,
|
|
17393
|
-
velocityMax: 60,
|
|
17394
|
-
angleMin: -PI2 * 0.9,
|
|
17395
|
-
angleMax: -PI2 * 0.1,
|
|
17396
|
-
gravity: 120,
|
|
17397
|
-
tint: { r: 180, g: 140, b: 90 },
|
|
17398
|
-
scaleMin: 0.15,
|
|
17399
|
-
scaleMax: 0.3,
|
|
17400
|
-
lifetimeMin: 400,
|
|
17401
|
-
lifetimeMax: 700,
|
|
17402
|
-
fadeRate: -1.8
|
|
17403
|
-
},
|
|
17404
|
-
{
|
|
17405
|
-
spriteUrls: p(manifest, "scratch"),
|
|
17406
|
-
count: 2,
|
|
17407
|
-
originX,
|
|
17408
|
-
originY,
|
|
17409
|
-
spread: 5,
|
|
17410
|
-
velocityMin: 10,
|
|
17411
|
-
velocityMax: 30,
|
|
17412
|
-
angleMin: -PI2 * 0.7,
|
|
17413
|
-
angleMax: -PI2 * 0.3,
|
|
17414
|
-
gravity: 0,
|
|
17415
|
-
tint: { r: 255, g: 200, b: 150 },
|
|
17416
|
-
scaleMin: 0.25,
|
|
17417
|
-
scaleMax: 0.4,
|
|
17418
|
-
lifetimeMin: 200,
|
|
17419
|
-
lifetimeMax: 400,
|
|
17420
|
-
fadeRate: -3
|
|
17421
|
-
}
|
|
17422
|
-
];
|
|
17423
|
-
const sequences = [];
|
|
17424
|
-
const flashFrames = anim(manifest, "flash");
|
|
17425
|
-
if (flashFrames.length > 0) {
|
|
17426
|
-
sequences.push({
|
|
17427
|
-
frameUrls: flashFrames,
|
|
17428
|
-
originX,
|
|
17429
|
-
originY,
|
|
17430
|
-
frameDuration: 35,
|
|
17431
|
-
scale: 0.4
|
|
17432
|
-
});
|
|
17433
|
-
}
|
|
17434
|
-
return {
|
|
17435
|
-
particles: particles.filter((pc) => pc.spriteUrls.length > 0),
|
|
17436
|
-
sequences,
|
|
17437
|
-
overlays: [],
|
|
17438
|
-
screenShake: 4,
|
|
17439
|
-
screenFlash: null
|
|
17440
|
-
};
|
|
17441
|
-
},
|
|
17442
|
-
// =====================================================================
|
|
17443
|
-
// RANGED — muzzle + trace + smoke + explosion sequence
|
|
17444
|
-
// =====================================================================
|
|
17445
|
-
ranged: (originX, originY) => {
|
|
17446
|
-
const particles = [
|
|
17447
|
-
{
|
|
17448
|
-
spriteUrls: p(manifest, "muzzle"),
|
|
17449
|
-
count: 3,
|
|
17450
|
-
originX,
|
|
17451
|
-
originY,
|
|
17452
|
-
spread: 4,
|
|
17453
|
-
velocityMin: 60,
|
|
17454
|
-
velocityMax: 150,
|
|
17455
|
-
angleMin: -PI2 * 0.6,
|
|
17456
|
-
angleMax: -PI2 * 0.4,
|
|
17457
|
-
gravity: 0,
|
|
17458
|
-
tint: { r: 255, g: 220, b: 100 },
|
|
17459
|
-
scaleMin: 0.2,
|
|
17460
|
-
scaleMax: 0.4,
|
|
17461
|
-
lifetimeMin: 200,
|
|
17462
|
-
lifetimeMax: 400,
|
|
17463
|
-
fadeRate: -3
|
|
17464
|
-
},
|
|
17465
|
-
{
|
|
17466
|
-
spriteUrls: p(manifest, "trace"),
|
|
17467
|
-
count: 5,
|
|
17468
|
-
originX,
|
|
17469
|
-
originY,
|
|
17470
|
-
spread: 3,
|
|
17471
|
-
velocityMin: 100,
|
|
17472
|
-
velocityMax: 200,
|
|
17473
|
-
angleMin: -PI2 * 0.55,
|
|
17474
|
-
angleMax: -PI2 * 0.45,
|
|
17475
|
-
gravity: 0,
|
|
17476
|
-
tint: { r: 255, g: 200, b: 80 },
|
|
17477
|
-
scaleMin: 0.15,
|
|
17478
|
-
scaleMax: 0.3,
|
|
17479
|
-
lifetimeMin: 150,
|
|
17480
|
-
lifetimeMax: 300,
|
|
17481
|
-
fadeRate: -4
|
|
17482
|
-
},
|
|
17483
|
-
{
|
|
17484
|
-
spriteUrls: p(manifest, "smoke").slice(0, 3),
|
|
17485
|
-
count: 3,
|
|
17486
|
-
originX,
|
|
17487
|
-
originY: originY + 5,
|
|
17488
|
-
spread: 6,
|
|
17489
|
-
velocityMin: 10,
|
|
17490
|
-
velocityMax: 30,
|
|
17491
|
-
angleMin: -PI2 * 0.8,
|
|
17492
|
-
angleMax: -PI2 * 0.2,
|
|
17493
|
-
gravity: -20,
|
|
17494
|
-
tint: { r: 200, g: 200, b: 200 },
|
|
17495
|
-
scaleMin: 0.2,
|
|
17496
|
-
scaleMax: 0.35,
|
|
17497
|
-
lifetimeMin: 500,
|
|
17498
|
-
lifetimeMax: 800,
|
|
17499
|
-
fadeRate: -1.5
|
|
17500
|
-
}
|
|
17501
|
-
];
|
|
17502
|
-
const sequences = [];
|
|
17503
|
-
const explosionFrames = anim(manifest, "smokeExplosion");
|
|
17504
|
-
if (explosionFrames.length > 0) {
|
|
17505
|
-
sequences.push({
|
|
17506
|
-
frameUrls: explosionFrames,
|
|
17507
|
-
originX,
|
|
17508
|
-
originY,
|
|
17509
|
-
frameDuration: 50,
|
|
17510
|
-
scale: 0.35
|
|
17511
|
-
});
|
|
17512
|
-
}
|
|
17513
|
-
return {
|
|
17514
|
-
particles: particles.filter((pc) => pc.spriteUrls.length > 0),
|
|
17515
|
-
sequences,
|
|
17516
|
-
overlays: [],
|
|
17517
|
-
screenShake: 2,
|
|
17518
|
-
screenFlash: null
|
|
17519
|
-
};
|
|
17520
|
-
},
|
|
17521
|
-
// =====================================================================
|
|
17522
|
-
// MAGIC — twirl (purple) + spark (purple) + star
|
|
17523
|
-
// =====================================================================
|
|
17524
|
-
magic: (originX, originY) => {
|
|
17525
|
-
const particles = [
|
|
17526
|
-
{
|
|
17527
|
-
spriteUrls: p(manifest, "twirl"),
|
|
17528
|
-
count: 5,
|
|
17529
|
-
originX,
|
|
17530
|
-
originY,
|
|
17531
|
-
spread: 15,
|
|
17532
|
-
velocityMin: 20,
|
|
17533
|
-
velocityMax: 80,
|
|
17534
|
-
angleMin: 0,
|
|
17535
|
-
angleMax: PI2 * 2,
|
|
17536
|
-
gravity: -30,
|
|
17537
|
-
tint: { r: 180, g: 80, b: 255 },
|
|
17538
|
-
scaleMin: 0.2,
|
|
17539
|
-
scaleMax: 0.5,
|
|
17540
|
-
lifetimeMin: 500,
|
|
17541
|
-
lifetimeMax: 900,
|
|
17542
|
-
fadeRate: -1.2,
|
|
17543
|
-
blendMode: "lighter",
|
|
17544
|
-
rotationSpeedMin: -4,
|
|
17545
|
-
rotationSpeedMax: 4
|
|
17546
|
-
},
|
|
17547
|
-
{
|
|
17548
|
-
spriteUrls: p(manifest, "spark"),
|
|
17549
|
-
count: 8,
|
|
17550
|
-
originX,
|
|
17551
|
-
originY,
|
|
17552
|
-
spread: 20,
|
|
17553
|
-
velocityMin: 30,
|
|
17554
|
-
velocityMax: 100,
|
|
17555
|
-
angleMin: 0,
|
|
17556
|
-
angleMax: PI2 * 2,
|
|
17557
|
-
gravity: -15,
|
|
17558
|
-
tint: { r: 200, g: 120, b: 255 },
|
|
17559
|
-
scaleMin: 0.1,
|
|
17560
|
-
scaleMax: 0.25,
|
|
17561
|
-
lifetimeMin: 300,
|
|
17562
|
-
lifetimeMax: 600,
|
|
17563
|
-
fadeRate: -2,
|
|
17564
|
-
blendMode: "lighter"
|
|
17565
|
-
},
|
|
17566
|
-
{
|
|
17567
|
-
spriteUrls: p(manifest, "star"),
|
|
17568
|
-
count: 4,
|
|
17569
|
-
originX,
|
|
17570
|
-
originY,
|
|
17571
|
-
spread: 10,
|
|
17572
|
-
velocityMin: 15,
|
|
17573
|
-
velocityMax: 50,
|
|
17574
|
-
angleMin: -PI2,
|
|
17575
|
-
angleMax: 0,
|
|
17576
|
-
gravity: -40,
|
|
17577
|
-
tint: { r: 220, g: 180, b: 255 },
|
|
17578
|
-
scaleMin: 0.15,
|
|
17579
|
-
scaleMax: 0.3,
|
|
17580
|
-
lifetimeMin: 600,
|
|
17581
|
-
lifetimeMax: 1e3,
|
|
17582
|
-
fadeRate: -1,
|
|
17583
|
-
blendMode: "lighter"
|
|
17584
|
-
}
|
|
17585
|
-
];
|
|
17586
|
-
const overlays = [];
|
|
17587
|
-
const circleUrls = p(manifest, "circle");
|
|
17588
|
-
if (circleUrls.length > 0) {
|
|
17589
|
-
overlays.push({
|
|
17590
|
-
spriteUrl: circleUrls[0],
|
|
17591
|
-
originX,
|
|
17592
|
-
originY,
|
|
17593
|
-
alpha: 0.5,
|
|
17594
|
-
fadeRate: -0.6,
|
|
17595
|
-
pulseAmplitude: 0.2,
|
|
17596
|
-
pulseFrequency: 3,
|
|
17597
|
-
scale: 0.5,
|
|
17598
|
-
blendMode: "lighter",
|
|
17599
|
-
lifetime: 1200
|
|
17600
|
-
});
|
|
17601
|
-
}
|
|
17602
|
-
return {
|
|
17603
|
-
particles: particles.filter((pc) => pc.spriteUrls.length > 0),
|
|
17604
|
-
sequences: [],
|
|
17605
|
-
overlays,
|
|
17606
|
-
screenShake: 0,
|
|
17607
|
-
screenFlash: null
|
|
17608
|
-
};
|
|
17609
|
-
},
|
|
17610
|
-
// =====================================================================
|
|
17611
|
-
// HEAL — circle (green) + star (green) + light (green, pulse)
|
|
17612
|
-
// =====================================================================
|
|
17613
|
-
heal: (originX, originY) => {
|
|
17614
|
-
const particles = [
|
|
17615
|
-
{
|
|
17616
|
-
spriteUrls: p(manifest, "circle"),
|
|
17617
|
-
count: 6,
|
|
17618
|
-
originX,
|
|
17619
|
-
originY,
|
|
17620
|
-
spread: 15,
|
|
17621
|
-
velocityMin: 10,
|
|
17622
|
-
velocityMax: 40,
|
|
17623
|
-
angleMin: -PI2,
|
|
17624
|
-
angleMax: -PI2 * 0.3,
|
|
17625
|
-
gravity: -50,
|
|
17626
|
-
tint: { r: 80, g: 255, b: 120 },
|
|
17627
|
-
scaleMin: 0.15,
|
|
17628
|
-
scaleMax: 0.35,
|
|
17629
|
-
lifetimeMin: 600,
|
|
17630
|
-
lifetimeMax: 1e3,
|
|
17631
|
-
fadeRate: -0.8,
|
|
17632
|
-
blendMode: "lighter"
|
|
17633
|
-
},
|
|
17634
|
-
{
|
|
17635
|
-
spriteUrls: p(manifest, "star"),
|
|
17636
|
-
count: 5,
|
|
17637
|
-
originX,
|
|
17638
|
-
originY,
|
|
17639
|
-
spread: 12,
|
|
17640
|
-
velocityMin: 15,
|
|
17641
|
-
velocityMax: 50,
|
|
17642
|
-
angleMin: -PI2 * 0.9,
|
|
17643
|
-
angleMax: -PI2 * 0.1,
|
|
17644
|
-
gravity: -60,
|
|
17645
|
-
tint: { r: 100, g: 255, b: 140 },
|
|
17646
|
-
scaleMin: 0.1,
|
|
17647
|
-
scaleMax: 0.2,
|
|
17648
|
-
lifetimeMin: 500,
|
|
17649
|
-
lifetimeMax: 800,
|
|
17650
|
-
fadeRate: -1.2,
|
|
17651
|
-
blendMode: "lighter"
|
|
17652
|
-
}
|
|
17653
|
-
];
|
|
17654
|
-
const overlays = [];
|
|
17655
|
-
const lightUrls = p(manifest, "light");
|
|
17656
|
-
if (lightUrls.length > 0) {
|
|
17657
|
-
overlays.push({
|
|
17658
|
-
spriteUrl: lightUrls[0],
|
|
17659
|
-
originX,
|
|
17660
|
-
originY,
|
|
17661
|
-
alpha: 0.6,
|
|
17662
|
-
fadeRate: -0.4,
|
|
17663
|
-
pulseAmplitude: 0.25,
|
|
17664
|
-
pulseFrequency: 2.5,
|
|
17665
|
-
scale: 0.6,
|
|
17666
|
-
blendMode: "lighter",
|
|
17667
|
-
lifetime: 1500
|
|
17668
|
-
});
|
|
17669
|
-
}
|
|
17670
|
-
return {
|
|
17671
|
-
particles: particles.filter((pc) => pc.spriteUrls.length > 0),
|
|
17672
|
-
sequences: [],
|
|
17673
|
-
overlays,
|
|
17674
|
-
screenShake: 0,
|
|
17675
|
-
screenFlash: null
|
|
17676
|
-
};
|
|
17677
|
-
},
|
|
17678
|
-
// =====================================================================
|
|
17679
|
-
// DEFEND / SHIELD — star (blue) + circle (blue, pulse)
|
|
17680
|
-
// =====================================================================
|
|
17681
|
-
defend: (originX, originY) => {
|
|
17682
|
-
const particles = [
|
|
17683
|
-
{
|
|
17684
|
-
spriteUrls: p(manifest, "star"),
|
|
17685
|
-
count: 8,
|
|
17686
|
-
originX,
|
|
17687
|
-
originY,
|
|
17688
|
-
spread: 18,
|
|
17689
|
-
velocityMin: 10,
|
|
17690
|
-
velocityMax: 35,
|
|
17691
|
-
angleMin: 0,
|
|
17692
|
-
angleMax: PI2 * 2,
|
|
17693
|
-
gravity: 0,
|
|
17694
|
-
tint: { r: 80, g: 160, b: 255 },
|
|
17695
|
-
scaleMin: 0.12,
|
|
17696
|
-
scaleMax: 0.25,
|
|
17697
|
-
lifetimeMin: 600,
|
|
17698
|
-
lifetimeMax: 1e3,
|
|
17699
|
-
fadeRate: -0.8,
|
|
17700
|
-
blendMode: "lighter",
|
|
17701
|
-
rotationSpeedMin: -1,
|
|
17702
|
-
rotationSpeedMax: 1
|
|
17703
|
-
}
|
|
17704
|
-
];
|
|
17705
|
-
const overlays = [];
|
|
17706
|
-
const circleUrls = p(manifest, "circle");
|
|
17707
|
-
if (circleUrls.length > 0) {
|
|
17708
|
-
overlays.push({
|
|
17709
|
-
spriteUrl: circleUrls[0],
|
|
17710
|
-
originX,
|
|
17711
|
-
originY,
|
|
17712
|
-
alpha: 0.6,
|
|
17713
|
-
fadeRate: -0.3,
|
|
17714
|
-
pulseAmplitude: 0.2,
|
|
17715
|
-
pulseFrequency: 2,
|
|
17716
|
-
scale: 0.6,
|
|
17717
|
-
blendMode: "lighter",
|
|
17718
|
-
lifetime: 1500
|
|
17719
|
-
});
|
|
17720
|
-
}
|
|
17721
|
-
return {
|
|
17722
|
-
particles: particles.filter((pc) => pc.spriteUrls.length > 0),
|
|
17723
|
-
sequences: [],
|
|
17724
|
-
overlays,
|
|
17725
|
-
screenShake: 0,
|
|
17726
|
-
screenFlash: null
|
|
17727
|
-
};
|
|
17728
|
-
},
|
|
17729
|
-
// shield aliases to defend
|
|
17730
|
-
shield: (originX, originY) => {
|
|
17731
|
-
const particles = [
|
|
17732
|
-
{
|
|
17733
|
-
spriteUrls: p(manifest, "star"),
|
|
17734
|
-
count: 10,
|
|
17735
|
-
originX,
|
|
17736
|
-
originY,
|
|
17737
|
-
spread: 20,
|
|
17738
|
-
velocityMin: 8,
|
|
17739
|
-
velocityMax: 30,
|
|
17740
|
-
angleMin: 0,
|
|
17741
|
-
angleMax: PI2 * 2,
|
|
17742
|
-
gravity: 0,
|
|
17743
|
-
tint: { r: 60, g: 180, b: 255 },
|
|
17744
|
-
scaleMin: 0.1,
|
|
17745
|
-
scaleMax: 0.22,
|
|
17746
|
-
lifetimeMin: 700,
|
|
17747
|
-
lifetimeMax: 1200,
|
|
17748
|
-
fadeRate: -0.7,
|
|
17749
|
-
blendMode: "lighter",
|
|
17750
|
-
rotationSpeedMin: -0.8,
|
|
17751
|
-
rotationSpeedMax: 0.8
|
|
17752
|
-
}
|
|
17753
|
-
];
|
|
17754
|
-
const overlays = [];
|
|
17755
|
-
const circleUrls = p(manifest, "circle");
|
|
17756
|
-
if (circleUrls.length > 0) {
|
|
17757
|
-
overlays.push({
|
|
17758
|
-
spriteUrl: circleUrls[0],
|
|
17759
|
-
originX,
|
|
17760
|
-
originY,
|
|
17761
|
-
alpha: 0.7,
|
|
17762
|
-
fadeRate: -0.25,
|
|
17763
|
-
pulseAmplitude: 0.25,
|
|
17764
|
-
pulseFrequency: 1.8,
|
|
17765
|
-
scale: 0.7,
|
|
17766
|
-
blendMode: "lighter",
|
|
17767
|
-
lifetime: 1800
|
|
17768
|
-
});
|
|
17769
|
-
}
|
|
17770
|
-
return {
|
|
17771
|
-
particles: particles.filter((pc) => pc.spriteUrls.length > 0),
|
|
17772
|
-
sequences: [],
|
|
17773
|
-
overlays,
|
|
17774
|
-
screenShake: 0,
|
|
17775
|
-
screenFlash: null
|
|
17776
|
-
};
|
|
17777
|
-
},
|
|
17778
|
-
// =====================================================================
|
|
17779
|
-
// HIT — spark (orange) + flash (5 frames) + screen shake/flash
|
|
17780
|
-
// =====================================================================
|
|
17781
|
-
hit: (originX, originY) => {
|
|
17782
|
-
const particles = [
|
|
17783
|
-
{
|
|
17784
|
-
spriteUrls: p(manifest, "spark"),
|
|
17785
|
-
count: 10,
|
|
17786
|
-
originX,
|
|
17787
|
-
originY,
|
|
17788
|
-
spread: 8,
|
|
17789
|
-
velocityMin: 50,
|
|
17790
|
-
velocityMax: 150,
|
|
17791
|
-
angleMin: 0,
|
|
17792
|
-
angleMax: PI2 * 2,
|
|
17793
|
-
gravity: 80,
|
|
17794
|
-
tint: { r: 255, g: 180, b: 50 },
|
|
17795
|
-
scaleMin: 0.08,
|
|
17796
|
-
scaleMax: 0.2,
|
|
17797
|
-
lifetimeMin: 200,
|
|
17798
|
-
lifetimeMax: 500,
|
|
17799
|
-
fadeRate: -2.5
|
|
17800
|
-
}
|
|
17801
|
-
];
|
|
17802
|
-
const sequences = [];
|
|
17803
|
-
const flashFrames = anim(manifest, "flash");
|
|
17804
|
-
if (flashFrames.length > 0) {
|
|
17805
|
-
sequences.push({
|
|
17806
|
-
frameUrls: flashFrames.slice(0, 5),
|
|
17807
|
-
originX,
|
|
17808
|
-
originY,
|
|
17809
|
-
frameDuration: 40,
|
|
17810
|
-
scale: 0.3
|
|
17811
|
-
});
|
|
17812
|
-
}
|
|
17813
|
-
return {
|
|
17814
|
-
particles: particles.filter((pc) => pc.spriteUrls.length > 0),
|
|
17815
|
-
sequences,
|
|
17816
|
-
overlays: [],
|
|
17817
|
-
screenShake: 3,
|
|
17818
|
-
screenFlash: { r: 255, g: 50, b: 50, duration: 150 }
|
|
17819
|
-
};
|
|
17820
|
-
},
|
|
17821
|
-
// critical aliases to hit with bigger shake
|
|
17822
|
-
critical: (originX, originY) => {
|
|
17823
|
-
const particles = [
|
|
17824
|
-
{
|
|
17825
|
-
spriteUrls: p(manifest, "flame"),
|
|
17826
|
-
count: 8,
|
|
17827
|
-
originX,
|
|
17828
|
-
originY,
|
|
17829
|
-
spread: 12,
|
|
17830
|
-
velocityMin: 60,
|
|
17831
|
-
velocityMax: 180,
|
|
17832
|
-
angleMin: 0,
|
|
17833
|
-
angleMax: PI2 * 2,
|
|
17834
|
-
gravity: 60,
|
|
17835
|
-
tint: { r: 255, g: 120, b: 30 },
|
|
17836
|
-
scaleMin: 0.15,
|
|
17837
|
-
scaleMax: 0.4,
|
|
17838
|
-
lifetimeMin: 300,
|
|
17839
|
-
lifetimeMax: 600,
|
|
17840
|
-
fadeRate: -2
|
|
17841
|
-
},
|
|
17842
|
-
{
|
|
17843
|
-
spriteUrls: p(manifest, "spark"),
|
|
17844
|
-
count: 12,
|
|
17845
|
-
originX,
|
|
17846
|
-
originY,
|
|
17847
|
-
spread: 10,
|
|
17848
|
-
velocityMin: 80,
|
|
17849
|
-
velocityMax: 200,
|
|
17850
|
-
angleMin: 0,
|
|
17851
|
-
angleMax: PI2 * 2,
|
|
17852
|
-
gravity: 100,
|
|
17853
|
-
tint: { r: 255, g: 200, b: 60 },
|
|
17854
|
-
scaleMin: 0.06,
|
|
17855
|
-
scaleMax: 0.18,
|
|
17856
|
-
lifetimeMin: 200,
|
|
17857
|
-
lifetimeMax: 400,
|
|
17858
|
-
fadeRate: -3
|
|
17859
|
-
}
|
|
17860
|
-
];
|
|
17861
|
-
const sequences = [];
|
|
17862
|
-
const flashFrames = anim(manifest, "flash");
|
|
17863
|
-
if (flashFrames.length > 0) {
|
|
17864
|
-
sequences.push({
|
|
17865
|
-
frameUrls: flashFrames,
|
|
17866
|
-
originX,
|
|
17867
|
-
originY,
|
|
17868
|
-
frameDuration: 30,
|
|
17869
|
-
scale: 0.5
|
|
17870
|
-
});
|
|
17871
|
-
}
|
|
17872
|
-
return {
|
|
17873
|
-
particles: particles.filter((pc) => pc.spriteUrls.length > 0),
|
|
17874
|
-
sequences,
|
|
17875
|
-
overlays: [],
|
|
17876
|
-
screenShake: 6,
|
|
17877
|
-
screenFlash: { r: 255, g: 80, b: 0, duration: 200 }
|
|
17878
|
-
};
|
|
17879
|
-
},
|
|
17880
|
-
// =====================================================================
|
|
17881
|
-
// DEATH — dirt (gray) + explosion + black smoke + scorch (ground)
|
|
17882
|
-
// =====================================================================
|
|
17883
|
-
death: (originX, originY) => {
|
|
17884
|
-
const particles = [
|
|
17885
|
-
{
|
|
17886
|
-
spriteUrls: p(manifest, "dirt"),
|
|
17887
|
-
count: 8,
|
|
17888
|
-
originX,
|
|
17889
|
-
originY,
|
|
17890
|
-
spread: 10,
|
|
17891
|
-
velocityMin: 30,
|
|
17892
|
-
velocityMax: 100,
|
|
17893
|
-
angleMin: 0,
|
|
17894
|
-
angleMax: PI2 * 2,
|
|
17895
|
-
gravity: 100,
|
|
17896
|
-
tint: { r: 140, g: 140, b: 140 },
|
|
17897
|
-
scaleMin: 0.15,
|
|
17898
|
-
scaleMax: 0.35,
|
|
17899
|
-
lifetimeMin: 500,
|
|
17900
|
-
lifetimeMax: 900,
|
|
17901
|
-
fadeRate: -1.2
|
|
17902
|
-
}
|
|
17903
|
-
];
|
|
17904
|
-
const sequences = [];
|
|
17905
|
-
const explosionFrames = anim(manifest, "explosion");
|
|
17906
|
-
if (explosionFrames.length > 0) {
|
|
17907
|
-
sequences.push({
|
|
17908
|
-
frameUrls: explosionFrames,
|
|
17909
|
-
originX,
|
|
17910
|
-
originY,
|
|
17911
|
-
frameDuration: 60,
|
|
17912
|
-
scale: 0.5
|
|
17913
|
-
});
|
|
17914
|
-
}
|
|
17915
|
-
const blackSmokeFrames = anim(manifest, "blackSmoke");
|
|
17916
|
-
if (blackSmokeFrames.length > 0) {
|
|
17917
|
-
sequences.push({
|
|
17918
|
-
frameUrls: blackSmokeFrames,
|
|
17919
|
-
originX,
|
|
17920
|
-
originY: originY - 10,
|
|
17921
|
-
frameDuration: 50,
|
|
17922
|
-
scale: 0.4,
|
|
17923
|
-
alpha: 0.7
|
|
17924
|
-
});
|
|
17925
|
-
}
|
|
17926
|
-
const overlays = [];
|
|
17927
|
-
const scorchUrls = p(manifest, "scorch");
|
|
17928
|
-
if (scorchUrls.length > 0) {
|
|
17929
|
-
overlays.push({
|
|
17930
|
-
spriteUrl: scorchUrls[0],
|
|
17931
|
-
originX,
|
|
17932
|
-
originY: originY + 10,
|
|
17933
|
-
alpha: 0.6,
|
|
17934
|
-
fadeRate: -0.15,
|
|
17935
|
-
scale: 0.4,
|
|
17936
|
-
lifetime: 4e3
|
|
17937
|
-
});
|
|
17938
|
-
}
|
|
17939
|
-
return {
|
|
17940
|
-
particles: particles.filter((pc) => pc.spriteUrls.length > 0),
|
|
17941
|
-
sequences,
|
|
17942
|
-
overlays,
|
|
17943
|
-
screenShake: 0,
|
|
17944
|
-
screenFlash: null
|
|
17945
|
-
};
|
|
17946
|
-
},
|
|
17947
|
-
// =====================================================================
|
|
17948
|
-
// BUFF — star (gold) + symbol + flare (gold, pulse)
|
|
17949
|
-
// =====================================================================
|
|
17950
|
-
buff: (originX, originY) => {
|
|
17951
|
-
const particles = [
|
|
17952
|
-
{
|
|
17953
|
-
spriteUrls: p(manifest, "star"),
|
|
17954
|
-
count: 6,
|
|
17955
|
-
originX,
|
|
17956
|
-
originY,
|
|
17957
|
-
spread: 15,
|
|
17958
|
-
velocityMin: 15,
|
|
17959
|
-
velocityMax: 50,
|
|
17960
|
-
angleMin: -PI2,
|
|
17961
|
-
angleMax: 0,
|
|
17962
|
-
gravity: -30,
|
|
17963
|
-
tint: { r: 255, g: 215, b: 50 },
|
|
17964
|
-
scaleMin: 0.12,
|
|
17965
|
-
scaleMax: 0.25,
|
|
17966
|
-
lifetimeMin: 600,
|
|
17967
|
-
lifetimeMax: 1e3,
|
|
17968
|
-
fadeRate: -0.8,
|
|
17969
|
-
blendMode: "lighter"
|
|
17970
|
-
},
|
|
17971
|
-
{
|
|
17972
|
-
spriteUrls: p(manifest, "symbol"),
|
|
17973
|
-
count: 2,
|
|
17974
|
-
originX,
|
|
17975
|
-
originY: originY - 10,
|
|
17976
|
-
spread: 8,
|
|
17977
|
-
velocityMin: 5,
|
|
17978
|
-
velocityMax: 20,
|
|
17979
|
-
angleMin: -PI2 * 0.7,
|
|
17980
|
-
angleMax: -PI2 * 0.3,
|
|
17981
|
-
gravity: -20,
|
|
17982
|
-
tint: { r: 255, g: 230, b: 100 },
|
|
17983
|
-
scaleMin: 0.2,
|
|
17984
|
-
scaleMax: 0.35,
|
|
17985
|
-
lifetimeMin: 800,
|
|
17986
|
-
lifetimeMax: 1200,
|
|
17987
|
-
fadeRate: -0.6,
|
|
17988
|
-
blendMode: "lighter"
|
|
17989
|
-
}
|
|
17990
|
-
];
|
|
17991
|
-
const overlays = [];
|
|
17992
|
-
const flareUrls = p(manifest, "flare");
|
|
17993
|
-
if (flareUrls.length > 0) {
|
|
17994
|
-
overlays.push({
|
|
17995
|
-
spriteUrl: flareUrls[0],
|
|
17996
|
-
originX,
|
|
17997
|
-
originY,
|
|
17998
|
-
alpha: 0.5,
|
|
17999
|
-
fadeRate: -0.3,
|
|
18000
|
-
pulseAmplitude: 0.3,
|
|
18001
|
-
pulseFrequency: 2,
|
|
18002
|
-
scale: 0.5,
|
|
18003
|
-
blendMode: "lighter",
|
|
18004
|
-
lifetime: 1500
|
|
18005
|
-
});
|
|
18006
|
-
}
|
|
18007
|
-
return {
|
|
18008
|
-
particles: particles.filter((pc) => pc.spriteUrls.length > 0),
|
|
18009
|
-
sequences: [],
|
|
18010
|
-
overlays,
|
|
18011
|
-
screenShake: 0,
|
|
18012
|
-
screenFlash: null
|
|
18013
|
-
};
|
|
18014
|
-
},
|
|
18015
|
-
// =====================================================================
|
|
18016
|
-
// DEBUFF — scorch (dark) + smoke (purple tint)
|
|
18017
|
-
// =====================================================================
|
|
18018
|
-
debuff: (originX, originY) => {
|
|
18019
|
-
const particles = [
|
|
18020
|
-
{
|
|
18021
|
-
spriteUrls: p(manifest, "scorch"),
|
|
18022
|
-
count: 4,
|
|
18023
|
-
originX,
|
|
18024
|
-
originY,
|
|
18025
|
-
spread: 12,
|
|
18026
|
-
velocityMin: 15,
|
|
18027
|
-
velocityMax: 40,
|
|
18028
|
-
angleMin: -PI2,
|
|
18029
|
-
angleMax: 0,
|
|
18030
|
-
gravity: -20,
|
|
18031
|
-
tint: { r: 120, g: 40, b: 160 },
|
|
18032
|
-
scaleMin: 0.15,
|
|
18033
|
-
scaleMax: 0.3,
|
|
18034
|
-
lifetimeMin: 500,
|
|
18035
|
-
lifetimeMax: 800,
|
|
18036
|
-
fadeRate: -1
|
|
18037
|
-
},
|
|
18038
|
-
{
|
|
18039
|
-
spriteUrls: p(manifest, "smoke").slice(0, 3),
|
|
18040
|
-
count: 3,
|
|
18041
|
-
originX,
|
|
18042
|
-
originY,
|
|
18043
|
-
spread: 10,
|
|
18044
|
-
velocityMin: 8,
|
|
18045
|
-
velocityMax: 25,
|
|
18046
|
-
angleMin: -PI2 * 0.8,
|
|
18047
|
-
angleMax: -PI2 * 0.2,
|
|
18048
|
-
gravity: -15,
|
|
18049
|
-
tint: { r: 100, g: 50, b: 140 },
|
|
18050
|
-
scaleMin: 0.2,
|
|
18051
|
-
scaleMax: 0.35,
|
|
18052
|
-
lifetimeMin: 600,
|
|
18053
|
-
lifetimeMax: 1e3,
|
|
18054
|
-
fadeRate: -0.8
|
|
18055
|
-
}
|
|
18056
|
-
];
|
|
18057
|
-
const overlays = [];
|
|
18058
|
-
const circleUrls = p(manifest, "circle");
|
|
18059
|
-
if (circleUrls.length > 0) {
|
|
18060
|
-
overlays.push({
|
|
18061
|
-
spriteUrl: circleUrls[0],
|
|
18062
|
-
originX,
|
|
18063
|
-
originY,
|
|
18064
|
-
alpha: 0.4,
|
|
18065
|
-
fadeRate: -0.4,
|
|
18066
|
-
pulseAmplitude: 0.15,
|
|
18067
|
-
pulseFrequency: 2,
|
|
18068
|
-
scale: 0.45,
|
|
18069
|
-
lifetime: 1200
|
|
18070
|
-
});
|
|
18071
|
-
}
|
|
18072
|
-
return {
|
|
18073
|
-
particles: particles.filter((pc) => pc.spriteUrls.length > 0),
|
|
18074
|
-
sequences: [],
|
|
18075
|
-
overlays,
|
|
18076
|
-
screenShake: 0,
|
|
18077
|
-
screenFlash: null
|
|
18078
|
-
};
|
|
18079
|
-
},
|
|
18080
|
-
// =====================================================================
|
|
18081
|
-
// AOE — explosion (large) + flame + spark (radial) + screen shake
|
|
18082
|
-
// =====================================================================
|
|
18083
|
-
aoe: (originX, originY) => {
|
|
18084
|
-
const particles = [
|
|
18085
|
-
{
|
|
18086
|
-
spriteUrls: p(manifest, "flame"),
|
|
18087
|
-
count: 10,
|
|
18088
|
-
originX,
|
|
18089
|
-
originY,
|
|
18090
|
-
spread: 20,
|
|
18091
|
-
velocityMin: 40,
|
|
18092
|
-
velocityMax: 140,
|
|
18093
|
-
angleMin: 0,
|
|
18094
|
-
angleMax: PI2 * 2,
|
|
18095
|
-
gravity: 40,
|
|
18096
|
-
tint: { r: 255, g: 140, b: 30 },
|
|
18097
|
-
scaleMin: 0.2,
|
|
18098
|
-
scaleMax: 0.5,
|
|
18099
|
-
lifetimeMin: 400,
|
|
18100
|
-
lifetimeMax: 800,
|
|
18101
|
-
fadeRate: -1.5
|
|
18102
|
-
},
|
|
18103
|
-
{
|
|
18104
|
-
spriteUrls: p(manifest, "spark"),
|
|
18105
|
-
count: 15,
|
|
18106
|
-
originX,
|
|
18107
|
-
originY,
|
|
18108
|
-
spread: 15,
|
|
18109
|
-
velocityMin: 60,
|
|
18110
|
-
velocityMax: 200,
|
|
18111
|
-
angleMin: 0,
|
|
18112
|
-
angleMax: PI2 * 2,
|
|
18113
|
-
gravity: 60,
|
|
18114
|
-
tint: { r: 255, g: 180, b: 60 },
|
|
18115
|
-
scaleMin: 0.06,
|
|
18116
|
-
scaleMax: 0.15,
|
|
18117
|
-
lifetimeMin: 200,
|
|
18118
|
-
lifetimeMax: 500,
|
|
18119
|
-
fadeRate: -2.5
|
|
18120
|
-
}
|
|
18121
|
-
];
|
|
18122
|
-
const sequences = [];
|
|
18123
|
-
const explosionFrames = anim(manifest, "explosion");
|
|
18124
|
-
if (explosionFrames.length > 0) {
|
|
18125
|
-
sequences.push({
|
|
18126
|
-
frameUrls: explosionFrames,
|
|
18127
|
-
originX,
|
|
18128
|
-
originY,
|
|
18129
|
-
frameDuration: 50,
|
|
18130
|
-
scale: 0.6
|
|
18131
|
-
});
|
|
18132
|
-
}
|
|
18133
|
-
return {
|
|
18134
|
-
particles: particles.filter((pc) => pc.spriteUrls.length > 0),
|
|
18135
|
-
sequences,
|
|
18136
|
-
overlays: [],
|
|
18137
|
-
screenShake: 5,
|
|
18138
|
-
screenFlash: { r: 255, g: 160, b: 0, duration: 180 }
|
|
18139
|
-
};
|
|
18140
|
-
}
|
|
18141
|
-
};
|
|
18142
|
-
}
|
|
18143
|
-
var PI2;
|
|
18144
|
-
var init_combatPresets = __esm({
|
|
18145
|
-
"components/game/shared/combatPresets.ts"() {
|
|
18146
|
-
PI2 = Math.PI;
|
|
18147
|
-
}
|
|
18148
|
-
});
|
|
18149
|
-
function CanvasEffectEngine({
|
|
18150
|
-
actionType,
|
|
18151
|
-
x,
|
|
18152
|
-
y,
|
|
18153
|
-
duration = 2e3,
|
|
18154
|
-
intensity = 1,
|
|
18155
|
-
onComplete,
|
|
18156
|
-
className,
|
|
18157
|
-
assetManifest,
|
|
18158
|
-
width = 400,
|
|
18159
|
-
height = 300
|
|
18160
|
-
}) {
|
|
18161
|
-
const canvasRef = useRef(null);
|
|
18162
|
-
const stateRef = useRef({ ...EMPTY_EFFECT_STATE });
|
|
18163
|
-
const lastTimeRef = useRef(0);
|
|
18164
|
-
const rafRef = useRef(0);
|
|
18165
|
-
const imageCacheRef = useRef(/* @__PURE__ */ new Map());
|
|
18166
|
-
const [shakeOffset, setShakeOffset] = useState({ x: 0, y: 0 });
|
|
18167
|
-
const [flash, setFlash] = useState(null);
|
|
18168
|
-
const shakeRef = useRef({ x: 0, y: 0, intensity: 0 });
|
|
18169
|
-
const presets = useMemo(() => createCombatPresets(assetManifest), [assetManifest]);
|
|
18170
|
-
const spriteUrls = useMemo(() => getAllEffectSpriteUrls(assetManifest), [assetManifest]);
|
|
18171
|
-
useEffect(() => {
|
|
18172
|
-
const cache = imageCacheRef.current;
|
|
18173
|
-
for (const url of spriteUrls) {
|
|
18174
|
-
if (!cache.has(url)) {
|
|
18175
|
-
const img = new Image();
|
|
18176
|
-
img.crossOrigin = "anonymous";
|
|
18177
|
-
img.src = url;
|
|
18178
|
-
cache.set(url, img);
|
|
18179
|
-
}
|
|
18180
|
-
}
|
|
18181
|
-
}, [spriteUrls]);
|
|
18182
|
-
const getImage = useCallback((url) => {
|
|
18183
|
-
const img = imageCacheRef.current.get(url);
|
|
18184
|
-
return img?.complete ? img : void 0;
|
|
18185
|
-
}, []);
|
|
18186
|
-
useEffect(() => {
|
|
18187
|
-
const now = performance.now();
|
|
18188
|
-
const effectX = x || width / 2;
|
|
18189
|
-
const effectY = y || height / 2;
|
|
18190
|
-
const preset = presets[actionType](effectX, effectY);
|
|
18191
|
-
const state = stateRef.current;
|
|
18192
|
-
for (const emitter of preset.particles) {
|
|
18193
|
-
const scaledEmitter = { ...emitter, count: Math.round(emitter.count * intensity) };
|
|
18194
|
-
state.particles.push(...spawnParticles(scaledEmitter, now));
|
|
18195
|
-
}
|
|
18196
|
-
for (const seqConfig of preset.sequences) {
|
|
18197
|
-
state.sequences.push(spawnSequence(seqConfig, now));
|
|
18198
|
-
}
|
|
18199
|
-
for (const ovConfig of preset.overlays) {
|
|
18200
|
-
state.overlays.push(spawnOverlay(ovConfig, now));
|
|
18201
|
-
}
|
|
18202
|
-
if (preset.screenShake > 0) {
|
|
18203
|
-
shakeRef.current.intensity = preset.screenShake * intensity;
|
|
18204
|
-
}
|
|
18205
|
-
if (preset.screenFlash) {
|
|
18206
|
-
const { r, g, b, duration: flashDur } = preset.screenFlash;
|
|
18207
|
-
setFlash({ color: `rgb(${r}, ${g}, ${b})`, alpha: 0.3 });
|
|
18208
|
-
setTimeout(() => setFlash(null), flashDur);
|
|
18209
|
-
}
|
|
18210
|
-
const timer = setTimeout(() => {
|
|
18211
|
-
onComplete?.();
|
|
18212
|
-
}, duration);
|
|
18213
|
-
return () => clearTimeout(timer);
|
|
18214
|
-
}, []);
|
|
18215
|
-
useEffect(() => {
|
|
18216
|
-
const canvas = canvasRef.current;
|
|
18217
|
-
if (!canvas) return;
|
|
18218
|
-
const ctx = canvas.getContext("2d");
|
|
18219
|
-
if (!ctx) return;
|
|
18220
|
-
function loop(animTime) {
|
|
18221
|
-
const delta = lastTimeRef.current > 0 ? animTime - lastTimeRef.current : 16;
|
|
18222
|
-
lastTimeRef.current = animTime;
|
|
18223
|
-
stateRef.current = updateEffectState(stateRef.current, animTime, delta);
|
|
18224
|
-
if (shakeRef.current.intensity > 0.2) {
|
|
18225
|
-
const i = shakeRef.current.intensity;
|
|
18226
|
-
shakeRef.current.x = (Math.random() - 0.5) * i * 2;
|
|
18227
|
-
shakeRef.current.y = (Math.random() - 0.5) * i * 2;
|
|
18228
|
-
shakeRef.current.intensity *= 0.85;
|
|
18229
|
-
setShakeOffset({ x: shakeRef.current.x, y: shakeRef.current.y });
|
|
18230
|
-
} else if (shakeRef.current.intensity > 0) {
|
|
18231
|
-
shakeRef.current = { x: 0, y: 0, intensity: 0 };
|
|
18232
|
-
setShakeOffset({ x: 0, y: 0 });
|
|
18233
|
-
}
|
|
18234
|
-
ctx.clearRect(0, 0, width, height);
|
|
18235
|
-
drawEffectState(ctx, stateRef.current, animTime, getImage);
|
|
18236
|
-
if (hasActiveEffects(stateRef.current)) {
|
|
18237
|
-
rafRef.current = requestAnimationFrame(loop);
|
|
18238
|
-
}
|
|
18239
|
-
}
|
|
18240
|
-
rafRef.current = requestAnimationFrame(loop);
|
|
18241
|
-
return () => cancelAnimationFrame(rafRef.current);
|
|
18242
|
-
}, [width, height, getImage]);
|
|
18243
|
-
const shakeStyle = shakeOffset.x !== 0 || shakeOffset.y !== 0 ? { transform: `translate(${shakeOffset.x}px, ${shakeOffset.y}px)` } : {};
|
|
18244
|
-
return /* @__PURE__ */ jsxs(
|
|
18245
|
-
Box,
|
|
18246
|
-
{
|
|
18247
|
-
className: cn("absolute inset-0 pointer-events-none z-10", className),
|
|
18248
|
-
style: shakeStyle,
|
|
18249
|
-
children: [
|
|
18250
|
-
flash && /* @__PURE__ */ jsx(
|
|
18251
|
-
Box,
|
|
18252
|
-
{
|
|
18253
|
-
className: "absolute inset-0 z-20 pointer-events-none rounded-container",
|
|
18254
|
-
style: { backgroundColor: flash.color, opacity: flash.alpha }
|
|
18255
|
-
}
|
|
18256
|
-
),
|
|
18257
|
-
/* @__PURE__ */ jsx(
|
|
18258
|
-
"canvas",
|
|
18259
|
-
{
|
|
18260
|
-
ref: canvasRef,
|
|
18261
|
-
width,
|
|
18262
|
-
height,
|
|
18263
|
-
className: "absolute inset-0 w-full h-full",
|
|
18264
|
-
style: { imageRendering: "pixelated" }
|
|
18265
|
-
}
|
|
18266
|
-
)
|
|
18267
|
-
]
|
|
18268
|
-
}
|
|
18269
|
-
);
|
|
18270
|
-
}
|
|
18271
|
-
function EmojiEffect({
|
|
18272
|
-
actionType,
|
|
18273
|
-
x,
|
|
18274
|
-
y,
|
|
18275
|
-
duration = 800,
|
|
18276
|
-
intensity = 1,
|
|
18277
|
-
onComplete,
|
|
18278
|
-
className,
|
|
18279
|
-
effectSpriteUrl,
|
|
18280
|
-
assetBaseUrl
|
|
18281
|
-
}) {
|
|
18282
|
-
const [visible, setVisible] = useState(true);
|
|
18283
|
-
const [phase, setPhase] = useState("enter");
|
|
18284
|
-
useEffect(() => {
|
|
18285
|
-
const enterTimer = setTimeout(() => setPhase("active"), 100);
|
|
18286
|
-
const exitTimer = setTimeout(() => setPhase("exit"), duration * 0.7);
|
|
18287
|
-
const doneTimer = setTimeout(() => {
|
|
18288
|
-
setVisible(false);
|
|
18289
|
-
onComplete?.();
|
|
18290
|
-
}, duration);
|
|
18291
|
-
return () => {
|
|
18292
|
-
clearTimeout(enterTimer);
|
|
18293
|
-
clearTimeout(exitTimer);
|
|
18294
|
-
clearTimeout(doneTimer);
|
|
18295
|
-
};
|
|
18296
|
-
}, [duration, onComplete]);
|
|
18297
|
-
if (!visible) return null;
|
|
18298
|
-
const config = ACTION_EMOJI[actionType] ?? ACTION_EMOJI.melee;
|
|
18299
|
-
const scaleVal = phase === "enter" ? 0.3 : phase === "active" ? intensity : 0.5;
|
|
18300
|
-
const opacity = phase === "exit" ? 0 : 1;
|
|
18301
|
-
const resolvedSpriteUrl = effectSpriteUrl ? effectSpriteUrl.startsWith("http") || effectSpriteUrl.startsWith("/") ? effectSpriteUrl : assetBaseUrl ? `${assetBaseUrl.replace(/\/$/, "")}/${effectSpriteUrl}` : effectSpriteUrl : void 0;
|
|
18302
|
-
return /* @__PURE__ */ jsxs(
|
|
18303
|
-
Box,
|
|
18304
|
-
{
|
|
18305
|
-
className: cn(
|
|
18306
|
-
"fixed pointer-events-none z-50 flex items-center justify-center",
|
|
18307
|
-
"transition-all ease-out",
|
|
18308
|
-
className
|
|
18309
|
-
),
|
|
18310
|
-
style: {
|
|
18311
|
-
left: x,
|
|
18312
|
-
top: y,
|
|
18313
|
-
transform: `translate(-50%, -50%) scale(${scaleVal})`,
|
|
18314
|
-
opacity,
|
|
18315
|
-
transitionDuration: phase === "enter" ? "100ms" : "300ms"
|
|
18316
|
-
},
|
|
18317
|
-
children: [
|
|
18318
|
-
/* @__PURE__ */ jsx(
|
|
18319
|
-
Box,
|
|
18320
|
-
{
|
|
18321
|
-
className: "absolute rounded-pill animate-ping",
|
|
18322
|
-
style: {
|
|
18323
|
-
width: 48 * intensity,
|
|
18324
|
-
height: 48 * intensity,
|
|
18325
|
-
backgroundColor: config.color,
|
|
18326
|
-
opacity: 0.25
|
|
18327
|
-
}
|
|
18328
|
-
}
|
|
18329
|
-
),
|
|
18330
|
-
resolvedSpriteUrl ? /* @__PURE__ */ jsx(
|
|
18331
|
-
"img",
|
|
18332
|
-
{
|
|
18333
|
-
src: resolvedSpriteUrl,
|
|
18334
|
-
alt: config.label,
|
|
18335
|
-
className: "relative drop-shadow-lg",
|
|
18336
|
-
style: {
|
|
18337
|
-
width: `${3 * intensity}rem`,
|
|
18338
|
-
height: `${3 * intensity}rem`,
|
|
18339
|
-
objectFit: "contain",
|
|
18340
|
-
imageRendering: "pixelated"
|
|
18341
|
-
}
|
|
18342
|
-
}
|
|
18343
|
-
) : /* @__PURE__ */ jsx(
|
|
18344
|
-
"span",
|
|
18345
|
-
{
|
|
18346
|
-
className: "relative text-3xl drop-shadow-lg",
|
|
18347
|
-
style: { fontSize: `${2 * intensity}rem` },
|
|
18348
|
-
role: "img",
|
|
18349
|
-
"aria-label": config.label,
|
|
18350
|
-
children: config.emoji
|
|
18351
|
-
}
|
|
18352
|
-
)
|
|
18353
|
-
]
|
|
18354
|
-
}
|
|
18355
|
-
);
|
|
18356
|
-
}
|
|
18357
|
-
function CanvasEffect({
|
|
18358
|
-
effectSpriteUrl,
|
|
18359
|
-
assetBaseUrl,
|
|
18360
|
-
...props
|
|
18361
|
-
}) {
|
|
18362
|
-
const eventBus = useEventBus();
|
|
18363
|
-
const mergedProps = { effectSpriteUrl, assetBaseUrl, ...props };
|
|
18364
|
-
const { completeEvent, onComplete, ...rest } = mergedProps;
|
|
18365
|
-
const handleComplete = useCallback(() => {
|
|
18366
|
-
if (completeEvent) eventBus.emit(`UI:${completeEvent}`, {});
|
|
18367
|
-
onComplete?.();
|
|
18368
|
-
}, [completeEvent, eventBus, onComplete]);
|
|
18369
|
-
const enhancedProps = { ...rest, onComplete: handleComplete };
|
|
18370
|
-
if (rest.assetManifest) {
|
|
18371
|
-
return /* @__PURE__ */ jsx(CanvasEffectEngine, { ...enhancedProps, assetManifest: rest.assetManifest });
|
|
18372
|
-
}
|
|
18373
|
-
return /* @__PURE__ */ jsx(EmojiEffect, { ...enhancedProps });
|
|
18374
|
-
}
|
|
18375
|
-
var ACTION_EMOJI;
|
|
18376
|
-
var init_CanvasEffect = __esm({
|
|
18377
|
-
"components/game/2d/organisms/CanvasEffect.tsx"() {
|
|
18378
|
-
"use client";
|
|
18379
|
-
init_cn();
|
|
18380
|
-
init_useEventBus();
|
|
18381
|
-
init_Box();
|
|
18382
|
-
init_effects();
|
|
18383
|
-
init_canvasEffects();
|
|
18384
|
-
init_combatPresets();
|
|
18385
|
-
ACTION_EMOJI = {
|
|
18386
|
-
melee: { emoji: "\u2694\uFE0F", color: "var(--color-error)", label: "Slash" },
|
|
18387
|
-
ranged: { emoji: "\u{1F3F9}", color: "var(--color-warning)", label: "Arrow" },
|
|
18388
|
-
magic: { emoji: "\u2728", color: "var(--color-primary)", label: "Spell" },
|
|
18389
|
-
heal: { emoji: "\u{1F49A}", color: "var(--color-success)", label: "Heal" },
|
|
18390
|
-
buff: { emoji: "\u2B06\uFE0F", color: "var(--color-info)", label: "Buff" },
|
|
18391
|
-
debuff: { emoji: "\u2B07\uFE0F", color: "var(--color-warning)", label: "Debuff" },
|
|
18392
|
-
shield: { emoji: "\u{1F6E1}\uFE0F", color: "var(--color-info)", label: "Shield" },
|
|
18393
|
-
aoe: { emoji: "\u{1F4A5}", color: "var(--color-error)", label: "Explosion" },
|
|
18394
|
-
critical: { emoji: "\u{1F525}", color: "var(--color-error)", label: "Critical" },
|
|
18395
|
-
defend: { emoji: "\u{1F6E1}\uFE0F", color: "var(--color-info)", label: "Defend" },
|
|
18396
|
-
hit: { emoji: "\u{1F4A5}", color: "var(--color-error)", label: "Hit" },
|
|
18397
|
-
death: { emoji: "\u{1F480}", color: "var(--color-error)", label: "Death" }
|
|
18398
|
-
};
|
|
18399
|
-
CanvasEffect.displayName = "CanvasEffect";
|
|
18400
|
-
}
|
|
18401
|
-
});
|
|
18402
|
-
|
|
18403
17131
|
// lib/getNestedValue.ts
|
|
18404
17132
|
function getNestedValue(obj, path) {
|
|
18405
17133
|
if (obj === null || obj === void 0 || !path) {
|
|
@@ -19186,10 +17914,10 @@ var init_Chart = __esm({
|
|
|
19186
17914
|
const set = [];
|
|
19187
17915
|
const seen = /* @__PURE__ */ new Set();
|
|
19188
17916
|
for (const s of series) {
|
|
19189
|
-
for (const
|
|
19190
|
-
if (!seen.has(
|
|
19191
|
-
seen.add(
|
|
19192
|
-
set.push(
|
|
17917
|
+
for (const p of s.data) {
|
|
17918
|
+
if (!seen.has(p.label)) {
|
|
17919
|
+
seen.add(p.label);
|
|
17920
|
+
set.push(p.label);
|
|
19193
17921
|
}
|
|
19194
17922
|
}
|
|
19195
17923
|
}
|
|
@@ -19197,8 +17925,8 @@ var init_Chart = __esm({
|
|
|
19197
17925
|
}, [series]);
|
|
19198
17926
|
const valueAt = useCallback(
|
|
19199
17927
|
(s, label) => {
|
|
19200
|
-
const
|
|
19201
|
-
return
|
|
17928
|
+
const p = s.data.find((d) => d.label === label);
|
|
17929
|
+
return p ? p.value : 0;
|
|
19202
17930
|
},
|
|
19203
17931
|
[]
|
|
19204
17932
|
);
|
|
@@ -19215,7 +17943,7 @@ var init_Chart = __esm({
|
|
|
19215
17943
|
}
|
|
19216
17944
|
let m = 1;
|
|
19217
17945
|
for (const s of series) {
|
|
19218
|
-
for (const
|
|
17946
|
+
for (const p of s.data) if (p.value > m) m = p.value;
|
|
19219
17947
|
}
|
|
19220
17948
|
return m;
|
|
19221
17949
|
}, [series, stack, columnTotals]);
|
|
@@ -19475,10 +18203,10 @@ var init_Chart = __esm({
|
|
|
19475
18203
|
const seen = /* @__PURE__ */ new Set();
|
|
19476
18204
|
const out = [];
|
|
19477
18205
|
for (const s of series) {
|
|
19478
|
-
for (const
|
|
19479
|
-
if (!seen.has(
|
|
19480
|
-
seen.add(
|
|
19481
|
-
out.push(
|
|
18206
|
+
for (const p of s.data) {
|
|
18207
|
+
if (!seen.has(p.label)) {
|
|
18208
|
+
seen.add(p.label);
|
|
18209
|
+
out.push(p.label);
|
|
19482
18210
|
}
|
|
19483
18211
|
}
|
|
19484
18212
|
}
|
|
@@ -19487,7 +18215,7 @@ var init_Chart = __esm({
|
|
|
19487
18215
|
const maxValue = useMemo(() => {
|
|
19488
18216
|
let m = 1;
|
|
19489
18217
|
for (const s of series) {
|
|
19490
|
-
for (const
|
|
18218
|
+
for (const p of s.data) if (p.value > m) m = p.value;
|
|
19491
18219
|
}
|
|
19492
18220
|
return m;
|
|
19493
18221
|
}, [series]);
|
|
@@ -19534,7 +18262,7 @@ var init_Chart = __esm({
|
|
|
19534
18262
|
label
|
|
19535
18263
|
};
|
|
19536
18264
|
});
|
|
19537
|
-
const linePath = points.map((
|
|
18265
|
+
const linePath = points.map((p, i) => `${i === 0 ? "M" : "L"} ${p.x} ${p.y}`).join(" ");
|
|
19538
18266
|
const areaPath = `${linePath} L ${points[points.length - 1]?.x ?? 0} ${padding.top + chartHeight} L ${padding.left} ${padding.top + chartHeight} Z`;
|
|
19539
18267
|
return /* @__PURE__ */ jsxs("g", { children: [
|
|
19540
18268
|
fill && /* @__PURE__ */ jsx(
|
|
@@ -19557,19 +18285,19 @@ var init_Chart = __esm({
|
|
|
19557
18285
|
strokeDasharray: s.dashed ? "6 4" : void 0
|
|
19558
18286
|
}
|
|
19559
18287
|
),
|
|
19560
|
-
points.map((
|
|
18288
|
+
points.map((p, idx) => /* @__PURE__ */ jsxs("g", { children: [
|
|
19561
18289
|
/* @__PURE__ */ jsx(
|
|
19562
18290
|
"circle",
|
|
19563
18291
|
{
|
|
19564
|
-
cx:
|
|
19565
|
-
cy:
|
|
18292
|
+
cx: p.x,
|
|
18293
|
+
cy: p.y,
|
|
19566
18294
|
r: "4",
|
|
19567
18295
|
fill: "var(--color-card)",
|
|
19568
18296
|
stroke: color,
|
|
19569
18297
|
strokeWidth: "2",
|
|
19570
18298
|
className: "cursor-pointer",
|
|
19571
18299
|
onClick: () => onPointClick?.(
|
|
19572
|
-
{ label:
|
|
18300
|
+
{ label: p.label, value: p.value, color },
|
|
19573
18301
|
s.name
|
|
19574
18302
|
)
|
|
19575
18303
|
}
|
|
@@ -19577,13 +18305,13 @@ var init_Chart = __esm({
|
|
|
19577
18305
|
showValues && series.length === 1 && /* @__PURE__ */ jsx(
|
|
19578
18306
|
"text",
|
|
19579
18307
|
{
|
|
19580
|
-
x:
|
|
19581
|
-
y:
|
|
18308
|
+
x: p.x,
|
|
18309
|
+
y: p.y - 10,
|
|
19582
18310
|
textAnchor: "middle",
|
|
19583
18311
|
fill: "var(--color-foreground)",
|
|
19584
18312
|
fontSize: "10",
|
|
19585
18313
|
fontWeight: "500",
|
|
19586
|
-
children:
|
|
18314
|
+
children: p.value
|
|
19587
18315
|
}
|
|
19588
18316
|
)
|
|
19589
18317
|
] }, idx))
|
|
@@ -19618,11 +18346,11 @@ var init_Chart = __esm({
|
|
|
19618
18346
|
let mxX = data[0].x;
|
|
19619
18347
|
let mnY = data[0].y;
|
|
19620
18348
|
let mxY = data[0].y;
|
|
19621
|
-
for (const
|
|
19622
|
-
if (
|
|
19623
|
-
if (
|
|
19624
|
-
if (
|
|
19625
|
-
if (
|
|
18349
|
+
for (const p of data) {
|
|
18350
|
+
if (p.x < mnX) mnX = p.x;
|
|
18351
|
+
if (p.x > mxX) mxX = p.x;
|
|
18352
|
+
if (p.y < mnY) mnY = p.y;
|
|
18353
|
+
if (p.y > mxY) mxY = p.y;
|
|
19626
18354
|
}
|
|
19627
18355
|
return { minX: mnX, maxX: mxX, minY: mnY, maxY: mxY };
|
|
19628
18356
|
}, [data]);
|
|
@@ -19652,11 +18380,11 @@ var init_Chart = __esm({
|
|
|
19652
18380
|
frac
|
|
19653
18381
|
);
|
|
19654
18382
|
}),
|
|
19655
|
-
data.map((
|
|
19656
|
-
const cx = padding.left + (
|
|
19657
|
-
const cy = padding.top + chartHeight - (
|
|
19658
|
-
const r =
|
|
19659
|
-
const color =
|
|
18383
|
+
data.map((p, idx) => {
|
|
18384
|
+
const cx = padding.left + (p.x - minX) / rangeX * chartWidth;
|
|
18385
|
+
const cy = padding.top + chartHeight - (p.y - minY) / rangeY * chartHeight;
|
|
18386
|
+
const r = p.size ?? 5;
|
|
18387
|
+
const color = p.color ?? CHART_COLORS[idx % CHART_COLORS.length];
|
|
19660
18388
|
return /* @__PURE__ */ jsx(
|
|
19661
18389
|
"circle",
|
|
19662
18390
|
{
|
|
@@ -19668,13 +18396,13 @@ var init_Chart = __esm({
|
|
|
19668
18396
|
className: "cursor-pointer hover:opacity-100",
|
|
19669
18397
|
onClick: () => onPointClick?.(
|
|
19670
18398
|
{
|
|
19671
|
-
label:
|
|
19672
|
-
value:
|
|
18399
|
+
label: p.label ?? `(${p.x}, ${p.y})`,
|
|
18400
|
+
value: p.y,
|
|
19673
18401
|
color
|
|
19674
18402
|
},
|
|
19675
18403
|
"default"
|
|
19676
18404
|
),
|
|
19677
|
-
children: /* @__PURE__ */ jsx("title", { children:
|
|
18405
|
+
children: /* @__PURE__ */ jsx("title", { children: p.label ?? `(${p.x}, ${p.y})` })
|
|
19678
18406
|
},
|
|
19679
18407
|
idx
|
|
19680
18408
|
);
|
|
@@ -24591,7 +23319,7 @@ var init_NodeSlotEditor = __esm({
|
|
|
24591
23319
|
}
|
|
24592
23320
|
}, []);
|
|
24593
23321
|
const options = React74__default.useMemo(
|
|
24594
|
-
() => [{ value: "", label: "\u2014 none \u2014" }, ...patterns.map((
|
|
23322
|
+
() => [{ value: "", label: "\u2014 none \u2014" }, ...patterns.map((p) => ({ value: p, label: p }))],
|
|
24595
23323
|
[patterns]
|
|
24596
23324
|
);
|
|
24597
23325
|
const emit = (nextType, nextProps) => {
|
|
@@ -26075,11 +24803,11 @@ var init_OnboardingSpotlight = __esm({
|
|
|
26075
24803
|
if (!step || typeof document === "undefined") return null;
|
|
26076
24804
|
const isLast = stepIndex >= steps.length - 1;
|
|
26077
24805
|
const backdrop = rect ? (() => {
|
|
26078
|
-
const
|
|
26079
|
-
const top = Math.max(0, rect.top -
|
|
26080
|
-
const left = Math.max(0, rect.left -
|
|
26081
|
-
const right = rect.right +
|
|
26082
|
-
const bottom = rect.bottom +
|
|
24806
|
+
const p = cutoutPadding;
|
|
24807
|
+
const top = Math.max(0, rect.top - p);
|
|
24808
|
+
const left = Math.max(0, rect.left - p);
|
|
24809
|
+
const right = rect.right + p;
|
|
24810
|
+
const bottom = rect.bottom + p;
|
|
26083
24811
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
26084
24812
|
/* @__PURE__ */ jsx("div", { className: DIM, style: { top: 0, left: 0, right: 0, height: top } }),
|
|
26085
24813
|
/* @__PURE__ */ jsx("div", { className: DIM, style: { top: bottom, left: 0, right: 0, bottom: 0 } }),
|
|
@@ -27595,7 +26323,7 @@ var init_LineChart = __esm({
|
|
|
27595
26323
|
}, [sortedData, width, height]);
|
|
27596
26324
|
const linePath = useMemo(() => {
|
|
27597
26325
|
if (points.length === 0) return "";
|
|
27598
|
-
return points.map((
|
|
26326
|
+
return points.map((p, i) => `${i === 0 ? "M" : "L"} ${p.x} ${p.y}`).join(" ");
|
|
27599
26327
|
}, [points]);
|
|
27600
26328
|
const areaPath = useMemo(() => {
|
|
27601
26329
|
if (points.length === 0 || !showArea) return "";
|
|
@@ -27801,6 +26529,18 @@ var init_game = __esm({
|
|
|
27801
26529
|
}
|
|
27802
26530
|
});
|
|
27803
26531
|
|
|
26532
|
+
// components/game/shared/effects.ts
|
|
26533
|
+
var EMPTY_EFFECT_STATE;
|
|
26534
|
+
var init_effects = __esm({
|
|
26535
|
+
"components/game/shared/effects.ts"() {
|
|
26536
|
+
EMPTY_EFFECT_STATE = {
|
|
26537
|
+
particles: [],
|
|
26538
|
+
sequences: [],
|
|
26539
|
+
overlays: []
|
|
26540
|
+
};
|
|
26541
|
+
}
|
|
26542
|
+
});
|
|
26543
|
+
|
|
27804
26544
|
// components/game/shared/makeAsset.ts
|
|
27805
26545
|
function makeAsset(url, role, overrides = {}) {
|
|
27806
26546
|
const defaults = ROLE_DEFAULTS[role] ?? { dimension: "2d", animations: ["static"], aspect: "1:1" };
|
|
@@ -27848,8 +26588,6 @@ var init_shared = __esm({
|
|
|
27848
26588
|
init_isometric();
|
|
27849
26589
|
init_spriteAnimation();
|
|
27850
26590
|
init_spriteSheetConstants();
|
|
27851
|
-
init_combatPresets();
|
|
27852
|
-
init_canvasEffects();
|
|
27853
26591
|
}
|
|
27854
26592
|
});
|
|
27855
26593
|
function GameCard({
|
|
@@ -29054,83 +27792,6 @@ var init_GameMenu = __esm({
|
|
|
29054
27792
|
GameMenu.displayName = "GameMenu";
|
|
29055
27793
|
}
|
|
29056
27794
|
});
|
|
29057
|
-
function useCanvasEffects({
|
|
29058
|
-
manifest
|
|
29059
|
-
}) {
|
|
29060
|
-
const stateRef = useRef({ ...EMPTY_EFFECT_STATE });
|
|
29061
|
-
const lastTimeRef = useRef(0);
|
|
29062
|
-
const shakeRef = useRef({ x: 0, y: 0, intensity: 0 });
|
|
29063
|
-
const [active, setActive] = useState(false);
|
|
29064
|
-
const [screenShake, setScreenShake] = useState({ x: 0, y: 0 });
|
|
29065
|
-
const [screenFlash, setScreenFlash] = useState(null);
|
|
29066
|
-
const effectSpriteUrls = useMemo(
|
|
29067
|
-
() => getAllEffectSpriteUrls(manifest),
|
|
29068
|
-
[manifest]
|
|
29069
|
-
);
|
|
29070
|
-
const presets = useMemo(
|
|
29071
|
-
() => createCombatPresets(manifest),
|
|
29072
|
-
[manifest]
|
|
29073
|
-
);
|
|
29074
|
-
const spawnEffect = useCallback((type, screenX, screenY) => {
|
|
29075
|
-
const now = performance.now();
|
|
29076
|
-
const preset = presets[type](screenX, screenY);
|
|
29077
|
-
const state = stateRef.current;
|
|
29078
|
-
for (const emitter of preset.particles) {
|
|
29079
|
-
state.particles.push(...spawnParticles(emitter, now));
|
|
29080
|
-
}
|
|
29081
|
-
for (const seqConfig of preset.sequences) {
|
|
29082
|
-
state.sequences.push(spawnSequence(seqConfig, now));
|
|
29083
|
-
}
|
|
29084
|
-
for (const ovConfig of preset.overlays) {
|
|
29085
|
-
state.overlays.push(spawnOverlay(ovConfig, now));
|
|
29086
|
-
}
|
|
29087
|
-
if (preset.screenShake > 0) {
|
|
29088
|
-
shakeRef.current.intensity = preset.screenShake;
|
|
29089
|
-
}
|
|
29090
|
-
if (preset.screenFlash) {
|
|
29091
|
-
const { r, g, b, duration } = preset.screenFlash;
|
|
29092
|
-
setScreenFlash({ color: `rgb(${r}, ${g}, ${b})`, alpha: 0.3 });
|
|
29093
|
-
setTimeout(() => setScreenFlash(null), duration);
|
|
29094
|
-
}
|
|
29095
|
-
setActive(true);
|
|
29096
|
-
}, [presets]);
|
|
29097
|
-
const drawEffects = useCallback((ctx, animTime, getImage) => {
|
|
29098
|
-
const delta = lastTimeRef.current > 0 ? animTime - lastTimeRef.current : 16;
|
|
29099
|
-
lastTimeRef.current = animTime;
|
|
29100
|
-
stateRef.current = updateEffectState(stateRef.current, animTime, delta);
|
|
29101
|
-
if (shakeRef.current.intensity > 0.2) {
|
|
29102
|
-
const i = shakeRef.current.intensity;
|
|
29103
|
-
shakeRef.current.x = (Math.random() - 0.5) * i * 2;
|
|
29104
|
-
shakeRef.current.y = (Math.random() - 0.5) * i * 2;
|
|
29105
|
-
shakeRef.current.intensity *= 0.85;
|
|
29106
|
-
setScreenShake({ x: shakeRef.current.x, y: shakeRef.current.y });
|
|
29107
|
-
} else if (shakeRef.current.intensity > 0) {
|
|
29108
|
-
shakeRef.current = { x: 0, y: 0, intensity: 0 };
|
|
29109
|
-
setScreenShake({ x: 0, y: 0 });
|
|
29110
|
-
}
|
|
29111
|
-
drawEffectState(ctx, stateRef.current, animTime, getImage);
|
|
29112
|
-
const isActive = hasActiveEffects(stateRef.current);
|
|
29113
|
-
if (!isActive && active) {
|
|
29114
|
-
setActive(false);
|
|
29115
|
-
}
|
|
29116
|
-
}, [active]);
|
|
29117
|
-
return {
|
|
29118
|
-
effectSpriteUrls,
|
|
29119
|
-
spawnEffect,
|
|
29120
|
-
drawEffects,
|
|
29121
|
-
hasActiveEffects: active,
|
|
29122
|
-
screenShake,
|
|
29123
|
-
screenFlash
|
|
29124
|
-
};
|
|
29125
|
-
}
|
|
29126
|
-
var init_useCanvasEffects = __esm({
|
|
29127
|
-
"components/game/shared/hooks/useCanvasEffects.ts"() {
|
|
29128
|
-
"use client";
|
|
29129
|
-
init_effects();
|
|
29130
|
-
init_canvasEffects();
|
|
29131
|
-
init_combatPresets();
|
|
29132
|
-
}
|
|
29133
|
-
});
|
|
29134
27795
|
function pickPath(entry) {
|
|
29135
27796
|
if (Array.isArray(entry.path)) {
|
|
29136
27797
|
return entry.path[Math.floor(Math.random() * entry.path.length)];
|
|
@@ -31817,7 +30478,7 @@ function NegotiatorBoard({
|
|
|
31817
30478
|
useEffect(() => {
|
|
31818
30479
|
if (currentRound > prevRoundRef.current && lastPlayerAction) {
|
|
31819
30480
|
const opponentPayoffEntry = payoffMatrix.find(
|
|
31820
|
-
(
|
|
30481
|
+
(p) => p.playerAction === lastPlayerAction && p.opponentAction === lastOpponentAction
|
|
31821
30482
|
);
|
|
31822
30483
|
setHistory((prev) => [
|
|
31823
30484
|
...prev,
|
|
@@ -32110,14 +30771,14 @@ function SimulationCanvas({
|
|
|
32110
30771
|
const ctx = canvas.getContext("2d");
|
|
32111
30772
|
if (!ctx) return;
|
|
32112
30773
|
const bodies = bodiesRef.current;
|
|
32113
|
-
const
|
|
30774
|
+
const p = presetRef.current;
|
|
32114
30775
|
const w = widthRef.current;
|
|
32115
30776
|
const h = heightRef.current;
|
|
32116
30777
|
ctx.clearRect(0, 0, w, h);
|
|
32117
|
-
ctx.fillStyle =
|
|
30778
|
+
ctx.fillStyle = p.backgroundColor ?? "#1a1a2e";
|
|
32118
30779
|
ctx.fillRect(0, 0, w, h);
|
|
32119
|
-
if (
|
|
32120
|
-
for (const c of
|
|
30780
|
+
if (p.constraints) {
|
|
30781
|
+
for (const c of p.constraints) {
|
|
32121
30782
|
const a = bodies[c.bodyA];
|
|
32122
30783
|
const b = bodies[c.bodyB];
|
|
32123
30784
|
if (a && b) {
|
|
@@ -32140,7 +30801,7 @@ function SimulationCanvas({
|
|
|
32140
30801
|
ctx.arc(pos.x, pos.y, body.radius, 0, Math.PI * 2);
|
|
32141
30802
|
ctx.fillStyle = body.color ?? "#e94560";
|
|
32142
30803
|
ctx.fill();
|
|
32143
|
-
if (
|
|
30804
|
+
if (p.showVelocity) {
|
|
32144
30805
|
ctx.beginPath();
|
|
32145
30806
|
ctx.moveTo(pos.x, pos.y);
|
|
32146
30807
|
ctx.lineTo(pos.x + body.vx * 0.1, pos.y + body.vy * 0.1);
|
|
@@ -32600,8 +31261,6 @@ var init_molecules = __esm({
|
|
|
32600
31261
|
init_GameMenu();
|
|
32601
31262
|
init_Canvas2D();
|
|
32602
31263
|
init_useUnitSpriteAtlas();
|
|
32603
|
-
init_CanvasEffect();
|
|
32604
|
-
init_useCanvasEffects();
|
|
32605
31264
|
init_GameAudioProvider();
|
|
32606
31265
|
init_GameAudioToggle();
|
|
32607
31266
|
init_useGameAudio();
|
|
@@ -32705,18 +31364,18 @@ var init_MathCanvas = __esm({
|
|
|
32705
31364
|
});
|
|
32706
31365
|
}
|
|
32707
31366
|
}
|
|
32708
|
-
for (const
|
|
32709
|
-
if (
|
|
31367
|
+
for (const p of points) {
|
|
31368
|
+
if (p.x < xMin || p.x > xMax || p.y < yMin || p.y > yMax) continue;
|
|
32710
31369
|
out.push({
|
|
32711
31370
|
type: "circle",
|
|
32712
|
-
x: mapX(
|
|
32713
|
-
y: mapY(
|
|
32714
|
-
radius:
|
|
32715
|
-
color:
|
|
32716
|
-
fill:
|
|
31371
|
+
x: mapX(p.x),
|
|
31372
|
+
y: mapY(p.y),
|
|
31373
|
+
radius: p.radius ?? 4,
|
|
31374
|
+
color: p.color ?? "#dc2626",
|
|
31375
|
+
fill: p.color ?? "#dc2626"
|
|
32717
31376
|
});
|
|
32718
|
-
if (
|
|
32719
|
-
out.push({ type: "text", x: mapX(
|
|
31377
|
+
if (p.label) {
|
|
31378
|
+
out.push({ type: "text", x: mapX(p.x) + 8, y: mapY(p.y) - 8, text: p.label, color: "#111827", fontSize: 12 });
|
|
32720
31379
|
}
|
|
32721
31380
|
}
|
|
32722
31381
|
for (const v of vectors) {
|
|
@@ -33235,13 +31894,13 @@ var init_MapView = __esm({
|
|
|
33235
31894
|
shadowSize: [41, 41]
|
|
33236
31895
|
});
|
|
33237
31896
|
L.Marker.prototype.options.icon = defaultIcon;
|
|
33238
|
-
const { useEffect:
|
|
31897
|
+
const { useEffect: useEffect71, useRef: useRef66, useCallback: useCallback114, useState: useState108 } = React74__default;
|
|
33239
31898
|
const { Typography: Typography2 } = await Promise.resolve().then(() => (init_Typography(), Typography_exports));
|
|
33240
31899
|
const { useEventBus: useEventBus2 } = await Promise.resolve().then(() => (init_useEventBus(), useEventBus_exports));
|
|
33241
31900
|
function MapUpdater({ centerLat, centerLng, zoom }) {
|
|
33242
31901
|
const map = useMap();
|
|
33243
|
-
const prevRef =
|
|
33244
|
-
|
|
31902
|
+
const prevRef = useRef66({ centerLat, centerLng, zoom });
|
|
31903
|
+
useEffect71(() => {
|
|
33245
31904
|
const prev = prevRef.current;
|
|
33246
31905
|
if (prev.centerLat !== centerLat || prev.centerLng !== centerLng || prev.zoom !== zoom) {
|
|
33247
31906
|
map.setView([centerLat, centerLng], zoom);
|
|
@@ -33252,7 +31911,7 @@ var init_MapView = __esm({
|
|
|
33252
31911
|
}
|
|
33253
31912
|
function MapClickHandler({ onMapClick }) {
|
|
33254
31913
|
const map = useMap();
|
|
33255
|
-
|
|
31914
|
+
useEffect71(() => {
|
|
33256
31915
|
if (!onMapClick) return;
|
|
33257
31916
|
const handler = (e) => {
|
|
33258
31917
|
onMapClick(e.latlng.lat, e.latlng.lng);
|
|
@@ -33280,8 +31939,8 @@ var init_MapView = __esm({
|
|
|
33280
31939
|
showAttribution = true
|
|
33281
31940
|
}) {
|
|
33282
31941
|
const eventBus = useEventBus2();
|
|
33283
|
-
const [clickedPosition, setClickedPosition] =
|
|
33284
|
-
const handleMapClick =
|
|
31942
|
+
const [clickedPosition, setClickedPosition] = useState108(null);
|
|
31943
|
+
const handleMapClick = useCallback114((lat, lng) => {
|
|
33285
31944
|
if (showClickedPin) {
|
|
33286
31945
|
setClickedPosition({ lat, lng });
|
|
33287
31946
|
}
|
|
@@ -33290,7 +31949,7 @@ var init_MapView = __esm({
|
|
|
33290
31949
|
eventBus.emit(`UI:${mapClickEvent}`, { latitude: lat, longitude: lng });
|
|
33291
31950
|
}
|
|
33292
31951
|
}, [onMapClick, mapClickEvent, eventBus, showClickedPin]);
|
|
33293
|
-
const handleMarkerClick =
|
|
31952
|
+
const handleMarkerClick = useCallback114((marker) => {
|
|
33294
31953
|
onMarkerClick?.(marker);
|
|
33295
31954
|
if (markerClickEvent) {
|
|
33296
31955
|
eventBus.emit(`UI:${markerClickEvent}`, { ...marker });
|
|
@@ -34363,7 +33022,7 @@ function TableView({
|
|
|
34363
33022
|
children: [
|
|
34364
33023
|
header,
|
|
34365
33024
|
dnd.wrapContainer(body),
|
|
34366
|
-
hasMore && /* @__PURE__ */ jsx(Box, { className: "flex justify-center py-3", children: /* @__PURE__ */ jsxs(Button, { variant: "ghost", size: "sm", onClick: () => setVisibleCount((
|
|
33025
|
+
hasMore && /* @__PURE__ */ jsx(Box, { className: "flex justify-center py-3", children: /* @__PURE__ */ jsxs(Button, { variant: "ghost", size: "sm", onClick: () => setVisibleCount((p) => p + (pageSize || 5)), children: [
|
|
34367
33026
|
/* @__PURE__ */ jsx(Icon, { name: "chevron-down", size: "xs", className: "mr-1" }),
|
|
34368
33027
|
t("common.showMore"),
|
|
34369
33028
|
" (",
|
|
@@ -37085,7 +35744,7 @@ var init_QrScanner = __esm({
|
|
|
37085
35744
|
setCurrentFacing((f3) => f3 === "environment" ? "user" : "environment");
|
|
37086
35745
|
}, []);
|
|
37087
35746
|
const togglePause = useCallback(() => {
|
|
37088
|
-
setIsPaused((
|
|
35747
|
+
setIsPaused((p) => !p);
|
|
37089
35748
|
}, []);
|
|
37090
35749
|
const handleMockScan = useCallback(() => {
|
|
37091
35750
|
const result = {
|
|
@@ -40007,10 +38666,10 @@ var init_ModuleCard = __esm({
|
|
|
40007
38666
|
] })
|
|
40008
38667
|
] }, trait.name);
|
|
40009
38668
|
}),
|
|
40010
|
-
pages.length > 0 && /* @__PURE__ */ jsx("div", { className: "px-3 py-1.5 flex items-center gap-2 flex-wrap", children: pages.map((
|
|
38669
|
+
pages.length > 0 && /* @__PURE__ */ jsx("div", { className: "px-3 py-1.5 flex items-center gap-2 flex-wrap", children: pages.map((p) => /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-0.5", children: [
|
|
40011
38670
|
/* @__PURE__ */ jsx("svg", { width: 10, height: 10, viewBox: "0 0 12 12", children: /* @__PURE__ */ jsx(AvlPage, { x: 6, y: 6, size: 5 }) }),
|
|
40012
|
-
/* @__PURE__ */ jsx("span", { className: "text-xs font-mono text-[var(--color-muted-foreground)]", children:
|
|
40013
|
-
] },
|
|
38671
|
+
/* @__PURE__ */ jsx("span", { className: "text-xs font-mono text-[var(--color-muted-foreground)]", children: p.route })
|
|
38672
|
+
] }, p.name)) })
|
|
40014
38673
|
]
|
|
40015
38674
|
}
|
|
40016
38675
|
);
|
|
@@ -41546,12 +40205,12 @@ var init_DocumentViewer = __esm({
|
|
|
41546
40205
|
const handleZoomIn = useCallback(() => setZoom((z) => Math.min(z + 25, 200)), []);
|
|
41547
40206
|
const handleZoomOut = useCallback(() => setZoom((z) => Math.max(z - 25, 50)), []);
|
|
41548
40207
|
const handlePagePrev = useCallback(() => {
|
|
41549
|
-
setCurrentPage((
|
|
40208
|
+
setCurrentPage((p) => Math.max(p - 1, 1));
|
|
41550
40209
|
eventBus.emit("UI:DOCUMENT_PAGE_CHANGE", { page: currentPage - 1 });
|
|
41551
40210
|
}, [eventBus, currentPage]);
|
|
41552
40211
|
const handlePageNext = useCallback(() => {
|
|
41553
40212
|
if (totalPages) {
|
|
41554
|
-
setCurrentPage((
|
|
40213
|
+
setCurrentPage((p) => Math.min(p + 1, totalPages));
|
|
41555
40214
|
eventBus.emit("UI:DOCUMENT_PAGE_CHANGE", { page: currentPage + 1 });
|
|
41556
40215
|
}
|
|
41557
40216
|
}, [totalPages, eventBus, currentPage]);
|
|
@@ -45850,7 +44509,7 @@ function WalkMinimap() {
|
|
|
45850
44509
|
const graphH = 120;
|
|
45851
44510
|
const nodeR = 10;
|
|
45852
44511
|
const positions = activeTrait ? layoutGraph(activeTrait.states, activeTrait.transitions, activeTrait.initialState, graphW, graphH) : [];
|
|
45853
|
-
const posMap = new Map(positions.map((
|
|
44512
|
+
const posMap = new Map(positions.map((p) => [p.state, p]));
|
|
45854
44513
|
const visitedStates = new Set(
|
|
45855
44514
|
coveredEdges.filter((e) => e.trait === walkStep.traitName).flatMap((e) => [e.from, e.to])
|
|
45856
44515
|
);
|
|
@@ -49120,7 +47779,6 @@ var init_component_registry_generated = __esm({
|
|
|
49120
47779
|
init_CTABanner();
|
|
49121
47780
|
init_CalendarGrid();
|
|
49122
47781
|
init_Canvas2D();
|
|
49123
|
-
init_CanvasEffect();
|
|
49124
47782
|
init_Card();
|
|
49125
47783
|
init_CardGrid();
|
|
49126
47784
|
init_Carousel();
|
|
@@ -49419,7 +48077,6 @@ var init_component_registry_generated = __esm({
|
|
|
49419
48077
|
"CTABanner": CTABanner,
|
|
49420
48078
|
"CalendarGrid": CalendarGrid,
|
|
49421
48079
|
"Canvas2D": Canvas2D,
|
|
49422
|
-
"CanvasEffect": CanvasEffect,
|
|
49423
48080
|
"Card": Card,
|
|
49424
48081
|
"CardGrid": CardGrid,
|
|
49425
48082
|
"Carousel": Carousel,
|
|
@@ -52906,4 +51563,4 @@ function useGitHubBranches(owner, repo, enabled = true) {
|
|
|
52906
51563
|
});
|
|
52907
51564
|
}
|
|
52908
51565
|
|
|
52909
|
-
export { ALL_PRESETS, ALMADAR_DND_MIME, AR_BOOK_FIELDS, AboutPageTemplate, Accordion, ActionButton, Card2 as ActionCard, ActionPalette, ActionTile, ActivationBlock, Alert, AnimatedCounter, AnimatedGraphic, AnimatedReveal, ArticleSection, Aside, AssetPicker, AuthLayout, Avatar, Badge, BehaviorView, BiologyCanvas, BloomQuizBlock, BookChapterView, BookCoverPage, BookNavBar, BookTableOfContents, BookViewer, Box, BranchingLogicBuilder, Breadcrumb, BuilderBoard, Button, ButtonGroup, CTABanner, CalendarGrid, Canvas2D,
|
|
51566
|
+
export { ALL_PRESETS, ALMADAR_DND_MIME, AR_BOOK_FIELDS, AboutPageTemplate, Accordion, ActionButton, Card2 as ActionCard, ActionPalette, ActionTile, ActivationBlock, Alert, AnimatedCounter, AnimatedGraphic, AnimatedReveal, ArticleSection, Aside, AssetPicker, AuthLayout, Avatar, Badge, BehaviorView, BiologyCanvas, BloomQuizBlock, BookChapterView, BookCoverPage, BookNavBar, BookTableOfContents, BookViewer, Box, BranchingLogicBuilder, Breadcrumb, BuilderBoard, Button, ButtonGroup, CTABanner, CalendarGrid, Canvas2D, Card, CardBody, CardContent, CardFooter, CardGrid, CardHeader, CardTitle, Carousel, CaseStudyCard, CaseStudyOrganism, Center, Chart, ChartLegend, ChatBar, Checkbox, ChemistryCanvas, ChoiceButton, ClassifierBoard, Coachmark, CodeBlock, CodeRunnerPanel, CollapsibleSection, ComboCounter, CommunityLinks, ConditionalWrapper, ConfettiEffect, ConfirmDialog, ConnectionBlock, Container, ContentRenderer, ContentSection, ControlButton, ControlGrid, CounterTemplate, DEFAULT_LIKERT_OPTIONS, DEFAULT_MATRIX_COLUMNS, DEFAULT_SLOTS, DIAMOND_TOP_Y, DamageNumber, DashboardGrid, DashboardLayout, DataGrid, DataList, DataTable, DateRangePicker, DateRangeSelector, DayCell, DebuggerBoard, DetailPanel, Dialog, DialogueBubble, Divider, DocBreadcrumb, DocPagination, DocSearch, DocSidebar, DocTOC, DocumentViewer, StateMachineView as DomStateMachineVisualizer, Drawer, DrawerSlot, ELEMENT_SELECTED_EVENT, EMPTY_EFFECT_STATE, EdgeDecoration, EditorCheckbox, EditorSelect, EditorSlider, EditorTextInput, EditorToolbar, EmptyState, EntityDisplayEvents, ErrorBoundary, ErrorState, EventHandlerBoard, EventLog, FEATURE_COLORS, FEATURE_TYPES, FLOOR_HEIGHT, FeatureCard, FeatureDetailPageTemplate, FeatureGrid, FeatureGridOrganism, FileTree, FilterGroup, FilterPill, Flex, FlipCard, FlipContainer, FloatingActionButton, Form, FormActions, FormField, FormLayout, FormSection, FormSectionHeader, GameAudioContext, GameAudioProvider, GameAudioToggle, GameCard, GameHud, GameIcon, GameMenu, GameShell, GameTemplate, GenericAppTemplate, GeometricPattern, GradientDivider, GraphCanvas, GraphView, Grid, GridPicker, HStack, Header, HealthBar, HeroOrganism, HeroSection, I18nProvider, IDENTITY_BOOK_FIELDS, Icon, IconPicker, InfiniteScrollSentinel, Input, InputGroup, InstallBox, InventoryGrid, ItemSlot, JazariStateMachine, JsonTreeEditor, Label, LandingPageTemplate, LawReferenceTooltip, LearningCanvas, Lightbox, LikertScale, LineChart2 as LineChart, List3 as List, LoadingState, MapView, MarkdownContent, MarketingFooter, MarketingStatCard, MasterDetail, MasterDetailLayout, MathCanvas, MatrixQuestion, MediaGallery, Menu, Meter, MiniMap, Modal, ModalSlot, ModuleCard, Navigation, NegotiatorBoard, NodeSlotEditor, NotifyListener, NumberStepper, ObjectRulePanel, OnboardingSpotlight, OptionConstraintGroup, StateMachineView as OrbitalStateMachineView, OrbitalVisualization, Overlay, PageHeader, Pagination, PatternTile, PhysicsCanvas, Popover, PositionedCanvas, PricingCard, PricingGrid, PricingOrganism, PricingPageTemplate, ProgressBar, ProgressDots, PropertyInspector, PullQuote, PullToRefresh, QrScanner, QuizBlock, Radio, RangeSlider, ReflectionBlock, RelationSelect, RepeatableFormSection, ReplyTree, ResourceBar, ResourceCounter, RichBlockEditor, RuleEditor, RuntimeDebugger, SHEET_COLUMNS, SPRITE_SHEET_LAYOUT, ScaledDiagram, ScoreDisplay, SearchInput, Section, SectionHeader, SegmentRenderer, Select, SequenceBar, SequencerBoard, ServiceCatalog, ShowcaseCard, ShowcaseOrganism, SidePanel, Sidebar, SignaturePad, SimpleGrid, SimulationCanvas, SimulationControls, SimulationGraph, SimulatorBoard, Skeleton, SlotContentRenderer, SocialProof, SortableList, Spacer, Sparkline, Spinner, Split, SplitPane, SplitSection, Sprite, Stack, StarRating, StatBadge, StatCard, StatDisplay, StateArchitectBoard, StateIndicator, StateJsonView, StateMachineView, StateNode2 as StateNode, StatsGrid, StatsOrganism, StatusBar, StatusDot, StatusEffect, StepFlow, StepFlowOrganism, SubagentTracePanel, SvgBranch, SvgConnection, SvgFlow, SvgGrid, SvgLobe, SvgMesh, SvgMorph, SvgNode, SvgPulse, SvgRing, SvgShield, SvgStack, SwipeableRow, Switch, TERRAIN_COLORS, TILE_HEIGHT, TILE_WIDTH, TabbedContainer, TableView, Tabs, TagCloud, TagInput, TeamCard, TeamOrganism, TerrainPalette, TextHighlight, Textarea, ThemeToggle, TimeSlotCell, Timeline, TimerDisplay, Toast, ToastSlot, Tooltip, TraitFrame, TraitSlot, TraitStateViewer, TransitionArrow, TrendIndicator, TurnIndicator, TypewriterText, Typography, UISlotComponent, UISlotRenderer, UploadDropZone, VStack, VariablePanel, VersionDiff, ViolationAlert, VoteStack, WaypointMarker, WizardContainer, WizardNavigation, WizardProgress, boardEntity, bool, calculateAttackTargets, calculateValidMoves, cn, createInitialGameState, createTranslate, createUnitAnimationState, drawSprite, getCurrentFrame, getTileDimensions, inferDirection, isoToScreen, makeAsset, makeAssetMap, mapBookData, num, objAvailableActions, objAvailableEvents, objCurrentState, objIcon, objId, objMaxRules, objName, objRules, objStates, parseEditFocus, parseLessonSegments, parseMarkdownWithCodeBlocks, parseQueryBinding, pendulum, projectileMotion, resolveFieldMap, resolveFrame, resolveSheetDirection, rows, screenToIso, springOscillator, str, tickAnimationState, toCodeLanguage, transitionAnimation, unitHealth, unitPosition, unitTeam, useAgentChat, useAnchorRect, useAuthContext, useCamera, useCanvasGestures, useCompile, useConnectGitHub, useDeepAgentGeneration, useDisconnectGitHub, useDragReorder, useDraggable, useDropZone, useEmitEvent, useEventBus, useEventListener, useExtensions, useFileEditor, useFileSystem, useGameAudio, useGameAudioContext, useGitHubBranches, useGitHubRepo, useGitHubRepos, useGitHubStatus, useImageCache, useInfiniteScroll, useLongPress, useOrbitalHistory, usePreview, usePullToRefresh, useQuerySingleton, useRenderInterpolation, useSwipeGesture, useTapReveal, useTraitListens, useTranslate127 as useTranslate, useUIEvents, useUISlotManager, useUnitSpriteAtlas, useValidation, vec2 };
|