403Webshell
Server IP : 202.61.199.114  /  Your IP : 216.73.217.139
Web Server : nginx/1.22.1
System : Linux de.arni-solutions.de 6.1.0-49-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.1.174-1 (2026-05-26) x86_64
User : web20 ( 1018)
PHP Version : 8.4.23
Disable Function : NONE
MySQL : OFF  |  cURL : ON  |  WGET : ON  |  Perl : ON  |  Python : OFF  |  Sudo : ON  |  Pkexec : ON
Directory :  /var/www/arni-solutions.de/web/slots/js/engine/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Command :


[ Back ]     

Current File : /var/www/arni-solutions.de/web/slots/js/engine/BonusEngine.js
/* Reel Royale – BonusEngine: animiertes Bonusrad (serverbestimmtes Ergebnis). */
import { $, money } from '../util.js';

export class BonusEngine {
  constructor(audio, particles) {
    this.audio = audio;
    this.particles = particles;
  }

  /** bonus = { segments:[...], index, multiplier, win } */
  async play(bonus, totalBet) {
    const overlay = $('bonusOverlay');
    const canvas = $('bonusWheel');
    const ctx = canvas.getContext('2d');
    const result = $('bonusResult');
    const closeBtn = $('bonusClose');
    result.textContent = '';
    closeBtn.hidden = true;
    overlay.hidden = false;
    this.audio.play('bonus');

    const segs = bonus.segments;
    const n = segs.length;
    const arc = (Math.PI * 2) / n;
    const colors = ['#ffce53', '#ff7a2c', '#56d6ff', '#4ad991', '#c77dff', '#ff5d6c', '#ffae2b', '#8be9fd'];
    const cx = canvas.width / 2, cy = canvas.height / 2, R = cx - 12;

    const draw = (rot) => {
      ctx.clearRect(0, 0, canvas.width, canvas.height);
      for (let i = 0; i < n; i++) {
        const a0 = rot + i * arc, a1 = a0 + arc;
        ctx.beginPath(); ctx.moveTo(cx, cy); ctx.arc(cx, cy, R, a0, a1); ctx.closePath();
        ctx.fillStyle = colors[i % colors.length]; ctx.fill();
        ctx.strokeStyle = 'rgba(0,0,0,.3)'; ctx.lineWidth = 2; ctx.stroke();
        ctx.save(); ctx.translate(cx, cy); ctx.rotate(a0 + arc / 2);
        ctx.fillStyle = '#1a1206'; ctx.font = 'bold 26px Cinzel, serif'; ctx.textAlign = 'right';
        ctx.fillText('×' + segs[i], R - 16, 9); ctx.restore();
      }
      // Nabe
      ctx.beginPath(); ctx.arc(cx, cy, 26, 0, 7); ctx.fillStyle = '#1c1530'; ctx.fill();
      ctx.strokeStyle = '#ffce53'; ctx.lineWidth = 3; ctx.stroke();
      // Zeiger (oben)
      ctx.beginPath(); ctx.moveTo(cx - 14, 6); ctx.lineTo(cx + 14, 6); ctx.lineTo(cx, 34); ctx.closePath();
      ctx.fillStyle = '#ffce53'; ctx.fill();
    };

    // Ziel: Index landet oben (−90°)
    const targetAngle = (-Math.PI / 2) - (bonus.index * arc) - arc / 2;
    const spins = 5;
    const finalRot = targetAngle - spins * Math.PI * 2;
    const startRot = 0;
    const dur = 3600;
    const t0 = performance.now();

    await new Promise((resolve) => {
      let lastTick = 0;
      const anim = (now) => {
        const t = Math.min(1, (now - t0) / dur);
        const eased = 1 - Math.pow(1 - t, 4);
        const rot = startRot + (finalRot - startRot) * eased;
        draw(rot);
        if (Math.floor(t * 40) !== lastTick) { lastTick = Math.floor(t * 40); if (t < 0.92) this.audio.play('click'); }
        if (t < 1) requestAnimationFrame(anim); else resolve();
      };
      requestAnimationFrame(anim);
    });

    this.audio.play('bigwin');
    this.particles.coinShower(50);
    result.innerHTML = `Bonus ×${bonus.multiplier} · <strong style="color:var(--rr-gold)">+${money(bonus.win)}</strong>`;
    closeBtn.hidden = false;

    // Automatisch einsammeln nach kurzer Zeit; Klick sammelt sofort ein.
    await new Promise((resolve) => {
      let done = false;
      let timer = null;
      const finish = () => {
        if (done) return;
        done = true;
        if (timer) clearTimeout(timer);
        overlay.hidden = true;
        closeBtn.removeEventListener('click', finish);
        resolve();
      };
      closeBtn.addEventListener('click', finish);
      timer = setTimeout(finish, 1800);
    });
  }
}

Youez - 2016 - github.com/yon3zu
LinuXploit