games: burial send-offs, money rain on wins, and honest stack targeting
Three front-end changes to the casino games:
- uno: a draw-card stack now names the seat it's actually pointed at
("+N on Beep") instead of always reading "+N on you". The bill reads
v.turn, which the engine advances to the target when a draw card lands.
- uno: the No Mercy rule buries a seat with some ceremony now. bury()
rolls one of four send-offs over the seat (or your hand, if it's you) —
a rockslide that piles up, a tombstone, a coffin, or the Mega Man death
burst — each with its own synth sound, and a static headstone under
reduced motion. The "Buried on N" badge still rides alongside.
- all games: winning makes it rain. FX.moneyRain drops a curtain of bills
and coins with a jackpot coin-cascade sound, gated by significance so it
reads as a win and not as noise: hold'em keeps its light per-pot confetti
and only rains on a real haul (>= 20bb), while the confetti stays the
rare cherry (natural 21, full board clear, phrase solved outright).
This commit is contained in:
@@ -319,6 +319,65 @@
|
||||
return Promise.all(done);
|
||||
}
|
||||
|
||||
// moneyRain: it rains money. The big finish on a win — bills and coins tumbling
|
||||
// the whole height of the window, swaying and spinning as they fall. Louder than
|
||||
// confetti, and it carries its own sound (a coin cascade) so it can stand in for
|
||||
// the plain win fanfare wherever a table decides a win is worth the theatre.
|
||||
//
|
||||
// Like burst, the sound comes before the reduced-motion bail: no rain still
|
||||
// deserves to be heard.
|
||||
function moneyRain(opts) {
|
||||
opts = opts || {};
|
||||
if (opts.sound !== false) sfx(opts.sound || "jackpot");
|
||||
if (reduced) return Promise.resolve();
|
||||
|
||||
var n = opts.count || 22;
|
||||
var glyphs = opts.glyphs || ["💶", "💰", "🪙", "💵", "💴", "🤑"];
|
||||
var vw = window.innerWidth || document.documentElement.clientWidth;
|
||||
var vh = window.innerHeight || document.documentElement.clientHeight;
|
||||
var done = [];
|
||||
|
||||
for (var i = 0; i < n; i++) {
|
||||
var bit = document.createElement("div");
|
||||
bit.className = "pete-money";
|
||||
bit.textContent = glyphs[i % glyphs.length];
|
||||
stage().appendChild(bit);
|
||||
|
||||
// Spread across the width in even lanes, each nudged off its lane so the
|
||||
// curtain doesn't read as a grid. It sways sideways and spins on the way down.
|
||||
var x = ((i + 0.5) / n) * vw + jitter(i, vw / n / 2);
|
||||
var drift = jitter(i + 5, 80);
|
||||
var startY = -50 - Math.abs(jitter(i + 2, 180));
|
||||
var spin = jitter(i, 300);
|
||||
var scale = 0.85 + Math.abs(jitter(i + 3, 0.55));
|
||||
|
||||
done.push(
|
||||
bit
|
||||
.animate(
|
||||
[
|
||||
{ transform: t(x, startY, scale, 0), opacity: 0, offset: 0 },
|
||||
{ transform: t(x + drift, startY + 40, scale, spin * 0.2), opacity: 1, offset: 0.1 },
|
||||
{ transform: t(x - drift, vh * 0.55, scale, spin * 0.6), opacity: 1, offset: 0.6 },
|
||||
{ transform: t(x + drift * 0.5, vh + 60, scale, spin), opacity: 1, offset: 1 },
|
||||
],
|
||||
{
|
||||
duration: 1600 + Math.abs(jitter(i + 9, 1)) * 900,
|
||||
easing: "cubic-bezier(0.35, 0.15, 0.55, 1)",
|
||||
fill: "both",
|
||||
delay: Math.abs(jitter(i, 320)),
|
||||
}
|
||||
)
|
||||
.finished.catch(function () {})
|
||||
.then(
|
||||
(function (b) {
|
||||
return function () { b.remove(); };
|
||||
})(bit)
|
||||
)
|
||||
);
|
||||
}
|
||||
return Promise.all(done);
|
||||
}
|
||||
|
||||
// count rolls a number to a new value instead of swapping it. A chip count that
|
||||
// jumps is a variable; one that climbs is a payout.
|
||||
function count(el, to, opts) {
|
||||
@@ -359,6 +418,7 @@
|
||||
flyMany: flyMany,
|
||||
spot: spot,
|
||||
burst: burst,
|
||||
moneyRain: moneyRain,
|
||||
count: count,
|
||||
centre: centre,
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user