"use strict";
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
var blackjack_exports = {};
__export(blackjack_exports, {
Blackjack: () => Blackjack,
commands: () => commands,
roomSettings: () => roomSettings
});
module.exports = __toCommonJS(blackjack_exports);
var import_lib = require("../../lib");
/**
* Blackjack Game
* Pokemon Showdown - http://pokemonshowdown.com/
*
* This allows users to play the classic blackjack card game.
* Credits: jd, panpawn
*
* @license MIT license
*/
class Blackjack extends Rooms.RoomGame {
constructor(room, user, autostartMinutes = 0) {
super(room);
this.gameNumber = room.nextGameNumber();
this.room = room;
this.turnTimeoutMinutes = 1;
this.timerTickSeconds = 5;
this.createdBy = user.name;
this.startedBy = "";
this.allowRenames = true;
this.playerCap = 16;
this.minimumPlayers = 2;
this.playerScrollWheel = 4;
this.cardWidth = 50;
this.cardHeight = 85;
this.spectators = /* @__PURE__ */ Object.create(null);
this.dealer = new BlackjackDealer();
this.symbols = {
"\u2665": "Hearts",
"\u2666": "Diamonds",
"\u2663": "Clubs",
"\u2660": "Spades"
};
this.deck = new BlackjackDeck().shuffle();
this.roomID = this.room.roomid;
this.title = `Blackjack (${room.title})`;
this.state = "signups";
this.lastMessage = "";
this.turnLog = "";
this.uhtmlChange = "";
this.curUsername = "";
this.endedBy = "";
this.infoboxLimited = "";
this.button = ' | ';
this.spectateButton = '';
this.slideButton = '';
this.autostart = null;
this.dqTimer = null;
this.timerTick = null;
this.makeGame(autostartMinutes);
}
/**
* Game Setup
* makeGame - configures required settings for creating a game
* makePlayer - adds blackjack-specific properties to player object
* sendInvite - called when a game is created, or when a player joins/leaves
*/
makeGame(autostartMinutes = 0) {
if (autostartMinutes > 0) {
this.autostart = setTimeout(() => this.start(), autostartMinutes * 6e4);
}
this.sendInvite();
}
makePlayer(user) {
return new BlackjackPlayer(user, this);
}
sendInvite() {
const change = this.uhtmlChange;
const players = Object.keys(this.playerTable);
const playerList = [];
for (const player of players)
playerList.push(import_lib.Utils.escapeHTML(this.playerTable[player].name));
this.room.send(`|uhtml${change}|blackjack-${this.gameNumber}|
${this.createdBy} has created a game of Blackjack. ${this.button} Players (${players.length}): ${!players.length ? "(None)" : playerList.join(", ")}
`);
this.uhtmlChange = "change";
}
/**
* Joining/Leaving/Viewing
* joinGame - joins the game
* leaveGame - leaves the game
* spectate - spectates the game
* unspectate - stops spectating the game
*/
joinGame(user) {
if (!user.named)
return this.errorMessage(user, `You must first choose a name to play Blackjack.`);
if (this.state === "started")
return this.errorMessage(user, `Blackjack has already started.`);
const joined = this.addPlayer(user);
if (!joined) {
this.errorMessage(user, `You are already in this game.`);
return false;
}
this.sendInvite();
if (Object.keys(this.playerTable).length === this.playerCap) {
this.start();
}
if (this.spectators[user.id])
delete this.spectators[user.id];
return true;
}
leaveGame(user) {
if (this.state === "started")
return this.errorMessage(user, `You cannot leave this game; it has already started.`);
if (!this.playerTable[user.id])
return this.errorMessage(user, "You are not in this game to leave.");
this.removePlayer(user);
this.sendInvite();
}
spectate(user) {
if (this.spectators[user.id])
return this.errorMessage(user, `You are already spectating this game.`);
if (this.playerTable[user.id]) {
return this.errorMessage(user, `You don't need to spectate the game; you're playing the game.`);
}
this.spectators[user.id] = user.id;
user.sendTo(this.roomid, `You are now spectating this game.`);
}
unspectate(user) {
if (!this.spectators[user.id])
return this.errorMessage(user, `You are already not spectating this game.`);
delete this.spectators[user.id];
user.sendTo(this.roomid, `You are no longer spectating this game.`);
}
/**
* Utility
* errorMessage - sends a user an error message
* add - adds/sends text to room
* display - displays gameplay to players and spectators
* clear - clears a user's gameplay screen
* clearAllTimers - clears all possible existing timers pertaining to blackjack
* slide - slides the game log down in the chat
* onConnect - handles replies to send when a user joins the room, if any
* onUpdateConnection - overrides default onUpdateConnection
* createTimer - creates a timer with a countdown for a player
* generateCard - generates the card for the UI
* getWinners - returns an array of the winners and their cards
*/
errorMessage(user, message) {
user.sendTo(this.room, import_lib.Utils.html`|html|
`);
this.lastMessage += message;
this.uhtmlChange = "change";
}
display(text, clean = false, playerName, noChange = false, end = false) {
const force = end && this.endedBy;
let change = this.uhtmlChange;
if (noChange)
change = "";
if (clean)
this.lastMessage = "";
const message = `|uhtml${change}|blackjack-${this.gameNumber}|
`;
this.lastMessage += text;
if (end) {
text = `The game of blackjack has ${force ? `been forcibly ended by ${this.endedBy}` : "ended"}. View turn log${this.turnLog}${text}`;
this.lastMessage = "";
}
for (const player of Object.keys(this.playerTable)) {
if (playerName && this.playerTable[player].name === playerName) {
this.playerTable[player].gameLog += `${text}`;
this.playerTable[player].sendRoom(`${message}${end ? text : this.playerTable[player].gameLog}
`);
} else {
this.playerTable[player].gameLog += text;
this.playerTable[player].sendRoom(`${message}${end ? text : this.playerTable[player].gameLog}`);
}
}
for (const spectatorID of Object.keys(this.spectators)) {
const spectator = Users.get(this.spectators[spectatorID]);
if (spectator)
spectator.sendTo(this.roomid, `${message}${this.lastMessage + text}`);
}
}
clear() {
const player = this.playerTable[this.curUsername];
if (!player)
throw new Error(`Player not in player table`);
player.sendRoom(`|uhtmlchange|user-blackjack-${this.gameNumber}|`);
}
clearAllTimers() {
if (this.dqTimer) {
clearTimeout(this.dqTimer);
this.dqTimer = null;
}
if (this.timerTick) {
clearInterval(this.timerTick);
this.timerTick = null;
}
if (this.autostart) {
clearTimeout(this.autostart);
this.autostart = null;
}
}
slide(user) {
user.sendTo(this.roomid, `|uhtml|blackjack-${this.gameNumber}|`);
this.display("", false, user.name);
}
onConnect(user) {
const message = `|uhtml|blackjack-${this.gameNumber}|
`;
if (this.state === "signups") {
this.sendInvite();
} else if (this.state === "started") {
const player = this.playerTable[user.id];
const spectator = this.spectators[user.id];
if (player && user.id === toID(this.curUsername)) {
player.sendRoom(`${message}${player.gameLog}`);
player.sendRoom(player.playScreen.replace("|uhtmlchange|", "|uhtml|"));
return;
} else if (player) {
player.sendRoom(`${message}${player.gameLog}`);
return;
} else if (spectator) {
user.sendTo(this.roomid, `${message}${this.lastMessage}`);
return;
}
}
}
onUpdateConnection() {
}
createTimer(user) {
const player = this.playerTable[user.id];
this.dqTimer = setTimeout(() => {
let cards = "";
for (const card of player.cards)
cards += `[${card}] `;
player.status = "stand";
this.display(
import_lib.Utils.html` ${player.name} stands with ${cards}` + ` (${player.points}) (Auto-stand: took too long to move)`,
false,
this.playerTable[this.curUsername].name
);
this.clear();
this.next();
}, this.turnTimeoutMinutes * 60 * 1e3);
this.timerTick = setInterval(() => {
const display = player.playScreen.replace("|uhtml|", "|uhtmlchange|");
if (display !== "") {
const timeLeft = player.timerTicksLeft - 5;
const buffer = String(timeLeft).length === 1 ? "0" : "";
const half = timeLeft <= this.turnTimeoutMinutes * 60 / 2;
player.sendRoom(`${display} | [ 0:${buffer}${timeLeft}]`);
player.timerTicksLeft -= this.timerTickSeconds;
}
}, this.timerTickSeconds * 1e3);
}
generateCard(card) {
const value = toID(card).toUpperCase();
const symbolName = this.symbols[card.substr(-1)];
const red = ["D", "H"].includes(symbolName.charAt(0));
let cardUI = value;
if (value === "K")
cardUI = "King";
if (value === "Q")
cardUI = "Queen";
if (value === "A")
cardUI = "Ace";
if (value === "J")
cardUI = "Joker";
return `