@energy8platform/shell 0.7.2 → 0.9.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/html.cjs.js +77 -11
- package/dist/html.cjs.js.map +1 -1
- package/dist/html.d.ts +14 -4
- package/dist/html.esm.js +77 -11
- package/dist/html.esm.js.map +1 -1
- package/dist/index.cjs.js +42 -3
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.ts +14 -4
- package/dist/index.esm.js +42 -3
- package/dist/index.esm.js.map +1 -1
- package/dist/pixi.cjs.js +322 -47
- package/dist/pixi.cjs.js.map +1 -1
- package/dist/pixi.d.ts +14 -4
- package/dist/pixi.esm.js +322 -47
- package/dist/pixi.esm.js.map +1 -1
- package/package.json +1 -1
- package/src/core/ShellController.ts +10 -2
- package/src/core/bonusGroups.ts +29 -0
- package/src/core/device.ts +37 -0
- package/src/core/types.ts +12 -2
- package/src/core/version.ts +1 -1
- package/src/ui/html/components/BottomBar.ts +20 -5
- package/src/ui/html/components/GameInfo.ts +8 -3
- package/src/ui/html/shell.css.ts +5 -0
- package/src/ui/pixi/components/BottomBar.ts +22 -3
- package/src/ui/pixi/components/BuyBonus.ts +195 -19
- package/src/ui/pixi/components/GameInfo.ts +8 -3
- package/src/ui/pixi/primitives/widgets.ts +65 -19
|
@@ -362,8 +362,20 @@ export interface SpinDiscOpts {
|
|
|
362
362
|
ticker: Ticker;
|
|
363
363
|
onSpin: () => void;
|
|
364
364
|
onStop: () => void;
|
|
365
|
+
/** Tapped in the halted-autoplay state — resume the run with the count still on the disc. */
|
|
366
|
+
onResume?: () => void;
|
|
365
367
|
}
|
|
366
368
|
|
|
369
|
+
/**
|
|
370
|
+
* What the disc is showing:
|
|
371
|
+
* - `off` — an ordinary SPIN disc;
|
|
372
|
+
* - `running` — STOP glyph over the live countdown;
|
|
373
|
+
* - `paused` — a run halted with spins still owed (a lost connection). The count stays put and a
|
|
374
|
+
* tap resumes; clearing it is the autoplay button's job. Certification asks for exactly this:
|
|
375
|
+
* the run stops, and after reconnection the counter is still there and still correct.
|
|
376
|
+
*/
|
|
377
|
+
export type SpinAutoplayMode = 'off' | 'running' | 'paused';
|
|
378
|
+
|
|
367
379
|
export class SpinDisc extends Container implements Sizable {
|
|
368
380
|
private size: number;
|
|
369
381
|
private glyphSize: number;
|
|
@@ -375,13 +387,14 @@ export class SpinDisc extends Container implements Sizable {
|
|
|
375
387
|
private glyph: IconView;
|
|
376
388
|
private dim = new Graphics();
|
|
377
389
|
private countText?: Text;
|
|
378
|
-
private mode: 'spin' | 'stop' = 'spin';
|
|
390
|
+
private mode: 'spin' | 'stop' | 'resume' = 'spin';
|
|
379
391
|
private _busy = false;
|
|
380
392
|
private _disabled = false;
|
|
381
393
|
private hovering = false;
|
|
382
394
|
private rotTick?: (t: Ticker) => void;
|
|
383
395
|
private onSpin: () => void;
|
|
384
396
|
private onStop: () => void;
|
|
397
|
+
private onResume: () => void;
|
|
385
398
|
|
|
386
399
|
constructor(opts: SpinDiscOpts) {
|
|
387
400
|
super();
|
|
@@ -391,6 +404,7 @@ export class SpinDisc extends Container implements Sizable {
|
|
|
391
404
|
this.ticker = opts.ticker;
|
|
392
405
|
this.onSpin = opts.onSpin;
|
|
393
406
|
this.onStop = opts.onStop;
|
|
407
|
+
this.onResume = opts.onResume ?? opts.onSpin;
|
|
394
408
|
this.disc = new Graphics();
|
|
395
409
|
this.glyph = makeIcon('spin', this.glyphSize, this.tokens.btnInk);
|
|
396
410
|
this.glyph.position.set((this.size - this.glyphSize) / 2, (this.size - this.glyphSize) / 2);
|
|
@@ -409,6 +423,7 @@ export class SpinDisc extends Container implements Sizable {
|
|
|
409
423
|
attachPress(this, 0.94, () => {
|
|
410
424
|
if (this._disabled) return;
|
|
411
425
|
if (this.mode === 'stop') this.onStop();
|
|
426
|
+
else if (this.mode === 'resume') this.onResume();
|
|
412
427
|
else this.onSpin();
|
|
413
428
|
});
|
|
414
429
|
}
|
|
@@ -420,8 +435,10 @@ export class SpinDisc extends Container implements Sizable {
|
|
|
420
435
|
drawDisc(this.disc, this.size, this.tokens.btn, 4);
|
|
421
436
|
const glyphColor = hot ? this.tokens.accent : this.tokens.btnInk;
|
|
422
437
|
this.glyph.setColor(glyphColor);
|
|
423
|
-
// the count sits ON the solid (btnInk) STOP square, so it must be light to read
|
|
424
|
-
|
|
438
|
+
// the count sits ON the solid (btnInk) STOP square, so it must be light to read; halted, it
|
|
439
|
+
// sits on the bare disc instead and takes the disc's own ink.
|
|
440
|
+
if (this.countText)
|
|
441
|
+
this.countText.style.fill = this.mode === 'resume' ? this.tokens.btnInk : '#ffffff';
|
|
425
442
|
// Disabled (mid-spin / can't spin): darken OPAQUELY (≈ filter:grayscale(.4) brightness(.62))
|
|
426
443
|
// with a dark veil over the disc — not alpha, which would let the bright board show through and
|
|
427
444
|
// read as a translucent/missing button (what looked "transparent" while spinning).
|
|
@@ -431,31 +448,44 @@ export class SpinDisc extends Container implements Sizable {
|
|
|
431
448
|
}
|
|
432
449
|
}
|
|
433
450
|
|
|
434
|
-
/** STOP glyph + remaining-count
|
|
435
|
-
setAutoplay(
|
|
436
|
-
if (
|
|
437
|
-
this.mode = 'stop';
|
|
438
|
-
this.stopRotation();
|
|
439
|
-
// STOP glyph at the disc's full size (like SPIN); the count is centred on top of it.
|
|
440
|
-
this.glyph.visible = false;
|
|
441
|
-
this.stopGlyph();
|
|
442
|
-
if (!this.countText) {
|
|
443
|
-
this.countText = makeText('', { size: 22, weight: '800', color: '#ffffff', align: 'center', family: NUM_FONT_FAMILY });
|
|
444
|
-
this.addChild(this.countText); // added after the STOP glyph → renders on top of it
|
|
445
|
-
}
|
|
446
|
-
const label = Number.isFinite(remaining) ? String(remaining) : '∞';
|
|
447
|
-
setText(this.countText, label);
|
|
448
|
-
this.countText.position.set((this.size - this.countText.width) / 2, (this.size - this.countText.height) / 2);
|
|
449
|
-
} else {
|
|
451
|
+
/** STOP glyph + remaining-count while autoplay runs; auto glyph + the same count once it halts. */
|
|
452
|
+
setAutoplay(mode: SpinAutoplayMode, remaining: number): void {
|
|
453
|
+
if (mode === 'off') {
|
|
450
454
|
this.mode = 'spin';
|
|
451
455
|
this.glyph.visible = true;
|
|
452
456
|
this.removeStopGlyph();
|
|
457
|
+
this.removeAutoGlyph();
|
|
453
458
|
if (this.countText) {
|
|
454
459
|
this.removeChild(this.countText);
|
|
455
460
|
this.countText.destroy();
|
|
456
461
|
this.countText = undefined;
|
|
457
462
|
}
|
|
463
|
+
this.paint();
|
|
464
|
+
return;
|
|
465
|
+
}
|
|
466
|
+
const running = mode === 'running';
|
|
467
|
+
this.mode = running ? 'stop' : 'resume';
|
|
468
|
+
this.stopRotation();
|
|
469
|
+
this.glyph.visible = false;
|
|
470
|
+
// Running: a solid STOP square at the disc's full size (like SPIN), count centred on top of it.
|
|
471
|
+
// Halted: the auto glyph, smaller and lifted, with the count under it — no dark square, because
|
|
472
|
+
// nothing is running to stop, and a white count would have nothing to read against.
|
|
473
|
+
if (running) {
|
|
474
|
+
this.removeAutoGlyph();
|
|
475
|
+
this.stopGlyph();
|
|
476
|
+
} else {
|
|
477
|
+
this.removeStopGlyph();
|
|
478
|
+
this.autoGlyph();
|
|
458
479
|
}
|
|
480
|
+
if (!this.countText) {
|
|
481
|
+
this.countText = makeText('', { size: 22, weight: '800', color: '#ffffff', align: 'center', family: NUM_FONT_FAMILY });
|
|
482
|
+
this.addChild(this.countText); // added after the glyph → renders on top of it
|
|
483
|
+
}
|
|
484
|
+
setText(this.countText, Number.isFinite(remaining) ? String(remaining) : '∞');
|
|
485
|
+
const cy = running
|
|
486
|
+
? (this.size - this.countText.height) / 2
|
|
487
|
+
: this.size * 0.56; // sits under the lifted auto glyph
|
|
488
|
+
this.countText.position.set((this.size - this.countText.width) / 2, cy);
|
|
459
489
|
this.paint();
|
|
460
490
|
}
|
|
461
491
|
|
|
@@ -475,6 +505,22 @@ export class SpinDisc extends Container implements Sizable {
|
|
|
475
505
|
}
|
|
476
506
|
}
|
|
477
507
|
|
|
508
|
+
private autoGlyphView?: IconView;
|
|
509
|
+
private autoGlyph(): void {
|
|
510
|
+
if (this.autoGlyphView) return;
|
|
511
|
+
const size = this.glyphSize * 0.42;
|
|
512
|
+
this.autoGlyphView = makeIcon('autoplay', size, this.tokens.btnInk);
|
|
513
|
+
this.autoGlyphView.position.set((this.size - size) / 2, this.size * 0.2);
|
|
514
|
+
this.addChild(this.autoGlyphView);
|
|
515
|
+
}
|
|
516
|
+
private removeAutoGlyph(): void {
|
|
517
|
+
if (this.autoGlyphView) {
|
|
518
|
+
this.removeChild(this.autoGlyphView);
|
|
519
|
+
this.autoGlyphView.destroy();
|
|
520
|
+
this.autoGlyphView = undefined;
|
|
521
|
+
}
|
|
522
|
+
}
|
|
523
|
+
|
|
478
524
|
setBusy(busy: boolean): void {
|
|
479
525
|
this._busy = busy;
|
|
480
526
|
if (busy && this.mode === 'spin') this.startRotation();
|