shalom
This commit is contained in:
185
app.js
185
app.js
@@ -2,6 +2,17 @@
|
||||
(function () {
|
||||
"use strict";
|
||||
|
||||
/* ===== DEBUG / ANTEPRIMA EFFETTI =====================================
|
||||
Per vedere gli effetti senza aspettare le vincite jacuzzi casuali.
|
||||
Rimetti entrambi a null/false per il gioco normale. */
|
||||
// Forza un effetto shalom fisso: "fire" | "video" | "combo" | "gesu" | null
|
||||
const FORCE_SHALOM = null;
|
||||
// Forza il risultato del giro su una stanza con idromassaggio (così l'effetto
|
||||
// parte a ogni giro). true = jacuzzi a caso; oppure l'id di una stanza
|
||||
// ("argo" | "eolo" | "rischio" | "zeus" | ...); false = risultato normale.
|
||||
const FORCE_RESULT = false;
|
||||
/* ==================================================================== */
|
||||
|
||||
const $ = (sel) => document.querySelector(sel);
|
||||
const roomById = Object.fromEntries(ROOMS.map((r) => [r.id, r]));
|
||||
const genderOf = Object.fromEntries(
|
||||
@@ -161,6 +172,8 @@
|
||||
win: "sounds/win.mp3", // jingle di vincita (match normale)
|
||||
jackpot: "sounds/jackpot.mp3", // sirena di jackpot (idromassaggio)
|
||||
coins: "sounds/coins.mp3", // pioggia di monete
|
||||
shalom: "sounds/shalom.mp3", // musica dell'effetto "shalom" (vittoria jacuzzi)
|
||||
gesuSong: "sounds/gesu_song.mp3", // canzone dell'effetto "Gesù"
|
||||
},
|
||||
el: {},
|
||||
ready: {},
|
||||
@@ -375,6 +388,146 @@
|
||||
});
|
||||
}
|
||||
|
||||
/* ---------- Effetto SHALOM (vittoria stanze con idromassaggio) ---------- */
|
||||
let shalomOverlay = null;
|
||||
function ensureShalomOverlay() {
|
||||
if (shalomOverlay) return shalomOverlay;
|
||||
const o = document.createElement("div");
|
||||
o.className = "shalom-overlay";
|
||||
o.innerHTML =
|
||||
'<div class="shalom-flames left"></div>' +
|
||||
'<div class="shalom-flames right"></div>' +
|
||||
'<img class="shalom-lion" src="image/lion.jpg" alt="" />' +
|
||||
'<div class="shalom-rays"></div>' +
|
||||
'<img class="shalom-gesu" src="image/gesu.jpeg" alt="" />' +
|
||||
'<video class="shalom-video" src="video/videoplayback.mp4" muted playsinline preload="auto"></video>' +
|
||||
'<div class="shalom-skip">tap per saltare ▸</div>';
|
||||
document.body.appendChild(o);
|
||||
shalomOverlay = o;
|
||||
return o;
|
||||
}
|
||||
function showShalom(o, mode) {
|
||||
o.classList.remove("mode-fire", "mode-video");
|
||||
o.classList.add("on", mode);
|
||||
}
|
||||
function hideShalom(o) {
|
||||
const v = o.querySelector(".shalom-video");
|
||||
try {
|
||||
v.pause();
|
||||
} catch (e) {}
|
||||
o.classList.remove("on", "mode-fire", "mode-video");
|
||||
}
|
||||
// Attende: fine video, tetto di tempo, oppure tap sull'overlay (skip).
|
||||
function shalomWait(v, capMs, o) {
|
||||
return new Promise((resolve) => {
|
||||
let done = false;
|
||||
const finish = () => {
|
||||
if (done) return;
|
||||
done = true;
|
||||
clearTimeout(to);
|
||||
if (v) v.removeEventListener("ended", finish);
|
||||
o.removeEventListener("pointerdown", finish);
|
||||
resolve();
|
||||
};
|
||||
const to = setTimeout(finish, capMs);
|
||||
if (v) v.addEventListener("ended", finish);
|
||||
o.addEventListener("pointerdown", finish);
|
||||
});
|
||||
}
|
||||
|
||||
// EFFETTO 1: fiammate dai due angoli in basso + leone (flashbang) ~3.5s
|
||||
async function shalomFireLion() {
|
||||
const o = ensureShalomOverlay();
|
||||
showShalom(o, "mode-fire");
|
||||
screenShake();
|
||||
const stop = Samples.play("shalom", {
|
||||
vol: 0.9,
|
||||
fallback: () => Audio.jackpot(),
|
||||
});
|
||||
await shalomWait(null, 3500, o);
|
||||
if (stop) stop(0.4);
|
||||
hideShalom(o);
|
||||
}
|
||||
|
||||
// EFFETTO 2: video a schermo intero con la musica shalom
|
||||
async function shalomVideoOnly() {
|
||||
const o = ensureShalomOverlay();
|
||||
const v = o.querySelector(".shalom-video");
|
||||
showShalom(o, "mode-video");
|
||||
const stop = Samples.play("shalom", {
|
||||
vol: 0.9,
|
||||
fallback: () => Audio.jackpot(),
|
||||
});
|
||||
try {
|
||||
v.currentTime = 0;
|
||||
await v.play();
|
||||
} catch (e) {}
|
||||
await shalomWait(v, 14000, o);
|
||||
if (stop) stop(0.4);
|
||||
hideShalom(o);
|
||||
}
|
||||
|
||||
// EFFETTO 3: combo — flashbang fuoco+leone 3s, poi parte il video con la musica
|
||||
async function shalomCombo() {
|
||||
const o = ensureShalomOverlay();
|
||||
showShalom(o, "mode-fire");
|
||||
screenShake();
|
||||
await shalomWait(null, 3000, o);
|
||||
const v = o.querySelector(".shalom-video");
|
||||
o.classList.remove("mode-fire");
|
||||
o.classList.add("mode-video");
|
||||
const stop = Samples.play("shalom", {
|
||||
vol: 0.9,
|
||||
fallback: () => Audio.jackpot(),
|
||||
});
|
||||
try {
|
||||
v.currentTime = 0;
|
||||
await v.play();
|
||||
} catch (e) {}
|
||||
await shalomWait(v, 14000, o);
|
||||
if (stop) stop(0.4);
|
||||
hideShalom(o);
|
||||
}
|
||||
|
||||
// EFFETTO 4: Gesù scende dall'alto con luce evangelica + canzone
|
||||
async function shalomGesu() {
|
||||
const o = ensureShalomOverlay();
|
||||
showShalom(o, "mode-gesu");
|
||||
const stop = Samples.play("gesuSong", {
|
||||
vol: 0.9,
|
||||
fallback: () => Audio.fanfare(),
|
||||
});
|
||||
await shalomWait(null, 14000, o);
|
||||
if (stop) stop(0.5);
|
||||
hideShalom(o);
|
||||
}
|
||||
|
||||
const SHALOM_EFFECTS = [
|
||||
shalomFireLion,
|
||||
shalomVideoOnly,
|
||||
shalomCombo,
|
||||
shalomGesu,
|
||||
];
|
||||
const SHALOM_BY_NAME = {
|
||||
fire: shalomFireLion,
|
||||
video: shalomVideoOnly,
|
||||
combo: shalomCombo,
|
||||
gesu: shalomGesu,
|
||||
};
|
||||
// "sacchetto" mescolato: a ogni vittoria jacuzzi esce un effetto DIVERSO
|
||||
// (senza ripetizioni) finché non sono usciti tutti, poi si rimescola.
|
||||
let shalomBag = [];
|
||||
function playShalom() {
|
||||
if (FORCE_SHALOM && SHALOM_BY_NAME[FORCE_SHALOM]) {
|
||||
return SHALOM_BY_NAME[FORCE_SHALOM](); // effetto fisso (debug)
|
||||
}
|
||||
if (shalomBag.length === 0) {
|
||||
shalomBag = Matching.shuffle(SHALOM_EFFECTS.slice(), Math.random);
|
||||
}
|
||||
const fx = shalomBag.shift();
|
||||
return fx();
|
||||
}
|
||||
|
||||
/* ---------- Sfondo three.js: pioggia di monete ---------- */
|
||||
function initBackground() {
|
||||
if (typeof THREE === "undefined") return;
|
||||
@@ -744,7 +897,10 @@
|
||||
function buildRevealOrder() {
|
||||
// ordine completamente casuale: ogni persona (e quindi ogni stanza, anche
|
||||
// quelle con idromassaggio) può uscire in qualsiasi momento
|
||||
return Matching.shuffle(PARTICIPANTS.map((p) => p.nome), Math.random);
|
||||
return Matching.shuffle(
|
||||
PARTICIPANTS.map((p) => p.nome),
|
||||
Math.random,
|
||||
);
|
||||
}
|
||||
|
||||
function newGame(keepChips) {
|
||||
@@ -755,6 +911,7 @@
|
||||
cursor = 0;
|
||||
currentBet = null;
|
||||
noMatchStreak = 0;
|
||||
shalomBag = [];
|
||||
if (!keepChips) {
|
||||
players = [
|
||||
{ name: "TU", chips: 100, you: true },
|
||||
@@ -932,7 +1089,15 @@
|
||||
Audio.resume();
|
||||
|
||||
const person = revealQueue[cursor];
|
||||
const roomId = assignment.byPerson[person];
|
||||
let roomId = assignment.byPerson[person];
|
||||
if (FORCE_RESULT) {
|
||||
// debug: forza il risultato su una jacuzzi (o su un id specifico)
|
||||
const jac = ROOMS.filter((r) => r.jacuzzi);
|
||||
roomId =
|
||||
typeof FORCE_RESULT === "string"
|
||||
? FORCE_RESULT
|
||||
: jac[Math.floor(Math.random() * jac.length)].id;
|
||||
}
|
||||
const room = roomById[roomId];
|
||||
|
||||
$("#player-name").textContent = person;
|
||||
@@ -952,7 +1117,8 @@
|
||||
|
||||
// 30% dei giri: NESSUN MATCH (3 stanze diverse) -> effetto pazzo + respin.
|
||||
// Tetto di 2 no-match di fila per non bloccare nessuno.
|
||||
const noMatch = noMatchStreak < 2 && Math.random() < NOMATCH_CHANCE;
|
||||
const noMatch =
|
||||
!FORCE_RESULT && noMatchStreak < 2 && Math.random() < NOMATCH_CHANCE;
|
||||
|
||||
if (noMatch) {
|
||||
noMatchStreak++;
|
||||
@@ -1021,6 +1187,12 @@
|
||||
// la macchina resta zoomata per godersi la vittoria, poi torna al posto
|
||||
setTimeout(zoomMachineOut, isJackpot ? 1200 : 800);
|
||||
|
||||
// EFFETTO SHALOM: vittoria di una stanza con idromassaggio -> effetto a caso
|
||||
if (isJackpot) {
|
||||
await sleep(600); // lascia vedere un attimo i coriandoli
|
||||
await playShalom();
|
||||
}
|
||||
|
||||
cursor++;
|
||||
setProgress();
|
||||
renderLeaderboard();
|
||||
@@ -1187,4 +1359,11 @@
|
||||
|
||||
// hook di debug (per test/verifica; innocuo)
|
||||
window.__celebrate = celebrate;
|
||||
window.__shalom = {
|
||||
fire: shalomFireLion,
|
||||
video: shalomVideoOnly,
|
||||
combo: shalomCombo,
|
||||
gesu: shalomGesu,
|
||||
random: playShalom,
|
||||
};
|
||||
})();
|
||||
|
||||
Reference in New Issue
Block a user