"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 uno_exports = {}; __export(uno_exports, { UNO: () => UNO, commands: () => commands, roomSettings: () => roomSettings }); module.exports = __toCommonJS(uno_exports); var import_lib = require("../../lib"); /** * UNO * Pokemon Showdown - http://pokemonshowdown.com/ * * This plugin allows rooms to run games of scripted UNO * * @license MIT license */ const maxTime = 60; const rgbGradients = { Green: "rgba(0, 122, 0, 1), rgba(0, 185, 0, 0.9)", Yellow: "rgba(255, 225, 0, 1), rgba(255, 255, 85, 0.9)", Blue: "rgba(40, 40, 255, 1), rgba(125, 125, 255, 0.9)", Red: "rgba(255, 0, 0, 1), rgba(255, 125, 125, 0.9)", Black: "rgba(0, 0, 0, 1), rgba(0, 0, 0, 0.55)" }; const textColors = { Green: "rgb(0, 128, 0)", Yellow: "rgb(175, 165, 40)", Blue: "rgb(75, 75, 255)", Red: "rgb(255, 0, 0)", Black: "inherit" }; const textShadow = "text-shadow: 1px 0px black, -1px 0px black, 0px -1px black, 0px 1px black, 2px -2px black;"; function cardHTML(card, fullsize) { let surface = card.value.replace(/[^A-Z0-9+]/g, ""); const background = rgbGradients[card.color]; if (surface === "R") surface = ''; return ``; } function createDeck() { const colors = ["Red", "Blue", "Green", "Yellow"]; const values = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "Reverse", "Skip", "+2"]; const basic = []; for (const color of colors) { basic.push(...values.map((v) => { const c = { value: v, color, name: `${color} ${v}` }; return c; })); } return [ // two copies of the basic stuff (total 96) ...basic, ...basic, // The four 0s ...[0, 1, 2, 3].map((v) => { const c = { color: colors[v], value: "0", name: `${colors[v]} 0` }; return c; }), // Wild cards ...[0, 1, 2, 3].map((v) => { const c = { color: "Black", value: "Wild", name: "Wild" }; return c; }), // Wild +4 cards ...[0, 1, 2, 3].map((v) => { const c = { color: "Black", value: "+4", name: "Wild +4" }; return c; }) ]; } class UNO extends Rooms.RoomGame { constructor(room, cap, suppressMessages) { super(room); this.gameNumber = room.nextGameNumber(); this.playerCap = cap; this.allowRenames = true; this.maxTime = maxTime; this.timer = null; this.autostartTimer = null; this.gameid = "uno"; this.title = "UNO"; this.state = "signups"; this.currentPlayerid = ""; this.deck = import_lib.Utils.shuffle(createDeck()); this.discards = []; this.topCard = null; this.awaitUno = null; this.unoId = null; this.isPlusFour = false; this.direction = 1; this.suppressMessages = suppressMessages || false; this.spectators = /* @__PURE__ */ Object.create(null); this.sendToRoom(`|uhtml|uno-${this.gameNumber}|

A new game of UNO is starting!

${this.suppressMessages ? `

Game messages won't show up unless you're playing or watching.

` : ""}
`, true); } onUpdateConnection() { } onConnect(user, connection) { if (this.state === "signups") { connection.sendTo( this.room, `|uhtml|uno-${this.gameNumber}|

A new game of UNO is starting!

${this.suppressMessages ? `

Game messages won't show up unless you're playing or watching.` : ""}

` ); } else if (this.onSendHand(user) === false) { connection.sendTo( this.room, `|uhtml|uno-${this.gameNumber}|

A game of UNO is currently in progress.

${this.suppressMessages ? `

Game messages won't show up unless you're playing or watching.` : ""}

` ); } } onStart(isAutostart) { if (this.playerCount < 2) { if (isAutostart) { this.room.add("The game of UNO was forcibly ended because there aren't enough users."); this.destroy(); return false; } else { throw new Chat.ErrorMessage("There must be at least 2 players to start a game of UNO."); } } if (this.autostartTimer) clearTimeout(this.autostartTimer); this.sendToRoom(`|uhtmlchange|uno-${this.gameNumber}|

The game of UNO has started.

${this.suppressMessages ? `

Game messages won't show up unless you're playing or watching.` : ""}

`, true); this.state = "play"; this.onNextPlayer(); for (const i in this.playerTable) { this.playerTable[i].hand.push(...this.drawCard(7)); } do { this.topCard = this.drawCard(1)[0]; this.discards.unshift(this.topCard); } while (this.topCard.color === "Black"); this.sendToRoom(`|raw|The top card is ${this.topCard.name}.`); this.onRunEffect(this.topCard.value, true); this.nextTurn(true); } joinGame(user) { if (user.id in this.playerTable) { throw new Chat.ErrorMessage("You have already joined the game of UNO."); } if (this.state === "signups" && this.addPlayer(user)) { this.sendToRoom(`${user.name} has joined the game of UNO.`); return true; } return false; } leaveGame(user) { if (!(user.id in this.playerTable)) return false; if (this.state === "signups" && this.removePlayer(user) || this.eliminate(user.id)) { this.sendToRoom(`${user.name} has left the game of UNO.`); return true; } return false; } /** * Overwrite the default makePlayer so it makes an UNOPlayer instead. */ makePlayer(user) { return new UNOPlayer(user, this); } onRename(user, oldUserid, isJoining, isForceRenamed) { if (!(oldUserid in this.playerTable) || user.id === oldUserid) return false; if (!user.named && !isForceRenamed) { user.games.delete(this.roomid); user.updateSearch(); return; } this.playerTable[user.id] = this.playerTable[oldUserid]; if (user.id !== oldUserid) delete this.playerTable[oldUserid]; this.playerTable[user.id].name = user.name; this.playerTable[user.id].id = user.id; if (this.awaitUno && this.awaitUno === oldUserid) this.awaitUno = user.id; if (this.currentPlayerid === oldUserid) this.currentPlayerid = user.id; } eliminate(userid) { if (!(userid in this.playerTable)) return false; const name = this.playerTable[userid].name; if (this.playerCount === 2) { this.removePlayer(this.playerTable[userid]); this.onWin(this.playerTable[Object.keys(this.playerTable)[0]]); return name; } const removingCurrentPlayer = userid === this.currentPlayerid; if (removingCurrentPlayer) { if (this.state === "color") { if (!this.topCard) { throw new Error(`No top card in the discard pile.`); } this.topCard.changedColor = this.discards[1].changedColor || this.discards[1].color; this.sendToRoom(`|raw|${import_lib.Utils.escapeHTML(name)} has not picked a color, the color will stay as ${this.topCard.changedColor}.`); } } if (this.awaitUno === userid) this.awaitUno = null; if (!this.topCard) { throw new Chat.ErrorMessage(`Unable to disqualify ${name}.`); } this.discards.push(...this.playerTable[userid].hand); if (removingCurrentPlayer) { this.onNextPlayer(); } this.removePlayer(this.playerTable[userid]); if (removingCurrentPlayer) { this.nextTurn(true); } return name; } sendToRoom(msg, overrideSuppress = false) { if (!this.suppressMessages || overrideSuppress) { this.room.add(msg).update(); } else { for (const i in this.playerTable) { this.playerTable[i].sendRoom(msg); } for (const i in this.spectators) { if (i in this.playerTable) continue; const user = Users.getExact(i); if (user) user.sendTo(this.roomid, msg); } } } getPlayers(showCards) { let playerList = Object.keys(this.playerTable); if (!showCards) { return playerList.sort().map((id) => import_lib.Utils.escapeHTML(this.playerTable[id].name)).join(", "); } if (this.direction === -1) playerList = playerList.reverse(); let buf = `
    `; for (const playerid of playerList) { buf += ``; buf += `${import_lib.Utils.escapeHTML(this.playerTable[playerid].name)} (${this.playerTable[playerid].hand.length})`; buf += ``; } buf += `
`; return buf; } onAwaitUno() { return new Promise((resolve) => { if (!this.awaitUno) return resolve(); this.state = "uno"; setTimeout(() => resolve(), 750); }); } nextTurn(starting) { void this.onAwaitUno().then(() => { if (!starting) this.onNextPlayer(); if (this.timer) clearTimeout(this.timer); const player = this.playerTable[this.currentPlayerid]; this.sendToRoom(`|c:|${Math.floor(Date.now() / 1e3)}|&|${player.name}'s turn.`); this.state = "play"; if (player.cardLock) player.cardLock = null; player.sendDisplay(); this.timer = setTimeout(() => { this.sendToRoom(`|c:|${Math.floor(Date.now() / 1e3)}|&|${player.name} has been automatically disqualified.`); this.eliminate(this.currentPlayerid); }, this.maxTime * 1e3); }); } onNextPlayer() { if (!this.currentPlayerid) { const userList = Object.keys(this.playerTable); this.currentPlayerid = userList[Math.floor(this.playerCount * Math.random())]; } this.currentPlayerid = this.getNextPlayer(); } getNextPlayer() { const userList = Object.keys(this.playerTable); let player = userList[userList.indexOf(this.currentPlayerid) + this.direction]; if (!player) { player = toID(this.direction === 1 ? userList[0] : userList[this.playerCount - 1]); } return player; } onDraw(player) { if (this.currentPlayerid !== player.id || this.state !== "play") return false; if (player.cardLock) return true; this.onCheckUno(); this.sendToRoom(`|c:|${Math.floor(Date.now() / 1e3)}|&|${player.name} has drawn a card.`); const card = this.onDrawCard(player, 1); player.sendDisplay(); player.cardLock = card[0].name; } onPlay(player, cardName) { if (this.currentPlayerid !== player.id || this.state !== "play") return false; const card = player.hasCard(cardName); if (!card) return "You do not have that card."; if (!this.topCard) { throw new Error(`No top card in the discard pile.`); } if (player.cardLock && player.cardLock !== cardName) return `You can only play ${player.cardLock} after drawing.`; if (card.color !== "Black" && card.color !== (this.topCard.changedColor || this.topCard.color) && card.value !== this.topCard.value) { return `You cannot play this card; you can only play: Wild cards, ${this.topCard.changedColor ? "and" : ""} ${this.topCard.changedColor || this.topCard.color} cards${this.topCard.changedColor ? "" : ` and cards with the digit ${this.topCard.value}`}.`; } if (card.value === "+4" && !player.canPlayWildFour()) { return "You cannot play Wild +4 when you still have a card with the same color as the top card."; } if (this.timer) clearTimeout(this.timer); this.onCheckUno(); this.topCard = card; player.removeCard(cardName); this.discards.unshift(card); if (player.hand.length === 1) { this.awaitUno = player.id; this.unoId = Math.floor(Math.random() * 100).toString(); } player.sendDisplay(); this.sendToRoom(`|raw|${import_lib.Utils.escapeHTML(player.name)} has played a ${card.name}.`); if (!player.hand.length) { this.onWin(player); return; } this.onRunEffect(card.value); if (this.state === "play") this.nextTurn(); } onRunEffect(value, initialize) { const colorDisplay = `|uhtml|uno-color|
`; switch (value) { case "Reverse": this.direction *= -1; this.sendToRoom(`|c:|${Math.floor(Date.now() / 1e3)}|&|The direction of the game has changed.`); if (!initialize && this.playerCount === 2) this.onNextPlayer(); break; case "Skip": this.onNextPlayer(); this.sendToRoom(`|c:|${Math.floor(Date.now() / 1e3)}|&|${this.playerTable[this.currentPlayerid].name}'s turn has been skipped.`); break; case "+2": this.onNextPlayer(); this.sendToRoom(`|c:|${Math.floor(Date.now() / 1e3)}|&|${this.playerTable[this.currentPlayerid].name} has been forced to draw 2 cards.`); this.onDrawCard(this.playerTable[this.currentPlayerid], 2); break; case "+4": this.playerTable[this.currentPlayerid].sendRoom(colorDisplay); this.state = "color"; const next = this.getNextPlayer(); this.sendToRoom(`|c:|${Math.floor(Date.now() / 1e3)}|&|${this.playerTable[next].name} has been forced to draw 4 cards.`); this.onDrawCard(this.playerTable[next], 4); this.isPlusFour = true; this.timer = setTimeout(() => { this.sendToRoom(`|c:|${Math.floor(Date.now() / 1e3)}|&|${this.playerTable[this.currentPlayerid].name} has been automatically disqualified.`); this.eliminate(this.currentPlayerid); }, this.maxTime * 1e3); break; case "Wild": this.playerTable[this.currentPlayerid].sendRoom(colorDisplay); this.state = "color"; this.timer = setTimeout(() => { this.sendToRoom(`|c:|${Math.floor(Date.now() / 1e3)}|&|${this.playerTable[this.currentPlayerid].name} has been automatically disqualified.`); this.eliminate(this.currentPlayerid); }, this.maxTime * 1e3); break; } if (initialize) this.onNextPlayer(); } onSelectColor(player, color) { if (!["Red", "Blue", "Green", "Yellow"].includes(color) || player.id !== this.currentPlayerid || this.state !== "color") { return false; } if (!this.topCard) { throw new Error(`No top card in the discard pile.`); } this.topCard.changedColor = color; this.sendToRoom(`|c:|${Math.floor(Date.now() / 1e3)}|&|The color has been changed to ${color}.`); if (this.timer) clearTimeout(this.timer); player.sendRoom("|uhtmlchange|uno-color|"); player.sendDisplay(); if (this.isPlusFour) { this.isPlusFour = false; this.onNextPlayer(); } this.nextTurn(); } onDrawCard(player, count) { if (typeof count === "string") count = parseInt(count); if (!count || isNaN(count) || count < 1) count = 1; const drawnCards = this.drawCard(count); player.hand.push(...drawnCards); player.sendRoom( `|raw|You have drawn the following card${Chat.plural(drawnCards)}: ${drawnCards.map((card) => `${card.name}`).join(", ")}.` ); return drawnCards; } drawCard(count) { if (typeof count === "string") count = parseInt(count); if (!count || isNaN(count) || count < 1) count = 1; const drawnCards = []; for (let i = 0; i < count; i++) { if (!this.deck.length) { this.deck = this.discards.length ? import_lib.Utils.shuffle(this.discards) : import_lib.Utils.shuffle(createDeck()); this.discards = []; } drawnCards.push(this.deck[this.deck.length - 1]); this.deck.pop(); } return drawnCards; } onUno(player, unoId) { if (this.unoId !== unoId || player.id !== this.awaitUno) return false; this.sendToRoom(`|c:|${Math.floor(Date.now() / 1e3)}|&|**UNO!** ${player.name} is down to their last card!`); this.awaitUno = null; this.unoId = null; } onCheckUno() { if (this.awaitUno) { if (this.awaitUno !== this.currentPlayerid) { this.sendToRoom(`|c:|${Math.floor(Date.now() / 1e3)}|&|${this.playerTable[this.awaitUno].name} forgot to say UNO! and is forced to draw 2 cards.`); this.onDrawCard(this.playerTable[this.awaitUno], 2); } this.awaitUno = null; this.unoId = null; } } onSendHand(user) { if (!(user.id in this.playerTable) || this.state === "signups") return false; this.playerTable[user.id].sendDisplay(); } onWin(player) { this.sendToRoom( import_lib.Utils.html`|raw|
Congratulations to ${player.name} for winning the game of UNO!
`, true ); this.destroy(); } destroy() { if (this.timer) clearTimeout(this.timer); if (this.autostartTimer) clearTimeout(this.autostartTimer); this.sendToRoom(`|uhtmlchange|uno-${this.gameNumber}|
The game of UNO has ended.
`, true); for (const i in this.playerTable) { this.playerTable[i].destroy(); } this.room.game = null; } } class UNOPlayer extends Rooms.RoomGamePlayer { constructor(user, game) { super(user, game); this.hand = []; this.cardLock = null; } canPlayWildFour() { if (!this.game.topCard) { throw new Error(`No top card in the discard pile.`); } const color = this.game.topCard.changedColor || this.game.topCard.color; if (this.hand.some((c) => c.color === color)) return false; return true; } hasCard(cardName) { return this.hand.find((card) => card.name === cardName); } removeCard(cardName) { for (const [i, card] of this.hand.entries()) { if (card.name === cardName) { this.hand.splice(i, 1); break; } } } buildHand() { return import_lib.Utils.sortBy(this.hand, (card) => [card.color, card.value]).map((card, i) => cardHTML(card, i === this.hand.length - 1)); } sendDisplay() { const hand = this.buildHand().join(""); const players = `

Players (${this.game.playerCount}):

${this.game.getPlayers(true)}`; const draw = ''; const pass = ''; const uno = ``; if (!this.game.topCard) { throw new Error(`No top card in the discard pile.`); } const top = `Top Card: ${this.game.topCard.name}`; this.sendRoom("|uhtmlchange|uno-hand|"); this.sendRoom( `|uhtml|uno-hand|
${this.game.currentPlayerid === this.id ? `` : ""}
${hand}
${top}
${players}
${this.game.currentPlayerid === this.id ? `
${draw}${pass}
${uno}
` : ""}
` ); } } const commands = { uno: { // roomowner commands off: "disable", disable(target, room, user) { room = this.requireRoom(); this.checkCan("gamemanagement", null, room); if (room.settings.unoDisabled) { throw new Chat.ErrorMessage("UNO is already disabled in this room."); } room.settings.unoDisabled = true; room.saveSettings(); return this.sendReply("UNO has been disabled for this room."); }, on: "enable", enable(target, room, user) { room = this.requireRoom(); this.checkCan("gamemanagement", null, room); if (!room.settings.unoDisabled) { throw new Chat.ErrorMessage("UNO is already enabled in this room."); } delete room.settings.unoDisabled; room.saveSettings(); return this.sendReply("UNO has been enabled for this room."); }, // moderation commands new: "create", make: "create", createpublic: "create", makepublic: "create", createprivate: "create", makeprivate: "create", create(target, room, user, connection, cmd) { room = this.requireRoom(); this.checkCan("minigame", null, room); if (room.settings.unoDisabled) throw new Chat.ErrorMessage("UNO is currently disabled for this room."); if (room.game) throw new Chat.ErrorMessage("There is already a game in progress in this room."); const suppressMessages = cmd.includes("private") || !(cmd.includes("public") || room.roomid === "gamecorner"); let cap = parseInt(target); if (isNaN(cap)) cap = 12; if (cap < 2) cap = 2; room.game = new UNO(room, cap, suppressMessages); this.privateModAction(`A game of UNO was created by ${user.name}.`); this.modlog("UNO CREATE"); }, cap: "setcap", setcap(target, room, user) { room = this.requireRoom(); this.checkCan("minigame", null, room); const game = this.requireGame(UNO); if (game.state !== "signups") { throw new Chat.ErrorMessage(`There is no UNO game in the signups phase in this room, so adjusting the player cap would do nothing.`); } let cap = parseInt(target); if (isNaN(cap) || cap < 2) { cap = 2; } game.playerCap = cap; this.privateModAction(`The playercap was set to ${game.playerCap} by ${user.name}.`); this.modlog("UNO PLAYERCAP"); }, start(target, room, user) { room = this.requireRoom(); this.checkCan("minigame", null, room); const game = this.requireGame(UNO); if (game.state !== "signups") { throw new Chat.ErrorMessage("There is no UNO game in signups phase in this room."); } game.onStart(); this.privateModAction(`The game of UNO was started by ${user.name}.`); this.modlog("UNO START"); }, stop: "end", end(target, room, user) { room = this.requireRoom(); this.checkCan("minigame", null, room); if (!room.game || room.game.gameid !== "uno") { throw new Chat.ErrorMessage("There is no UNO game going on in this room."); } room.game.destroy(); room.add("The game of UNO was forcibly ended.").update(); this.privateModAction(`The game of UNO was ended by ${user.name}.`); this.modlog("UNO END"); }, autodq: "timer", timer(target, room, user) { room = this.requireRoom(); this.checkCan("minigame", null, room); const game = this.requireGame(UNO); const amount = parseInt(target); if (!amount || amount < 5 || amount > 300) { throw new Chat.ErrorMessage("The amount must be a number between 5 and 300."); } game.maxTime = amount; if (game.timer) clearTimeout(game.timer); game.timer = setTimeout(() => { game.eliminate(game.currentPlayerid); }, amount * 1e3); this.addModAction(`${user.name} has set the UNO automatic disqualification timer to ${amount} seconds.`); this.modlog("UNO TIMER", null, `${amount} seconds`); }, autostart(target, room, user) { room = this.requireRoom(); this.checkCan("minigame", null, room); const game = this.requireGame(UNO); if (toID(target) === "off") { if (!game.autostartTimer) throw new Chat.ErrorMessage("There is no autostart timer running on."); this.addModAction(`${user.name} has turned off the UNO autostart timer.`); clearTimeout(game.autostartTimer); return; } const amount = parseInt(target); if (!amount || amount < 30 || amount > 600) { throw new Chat.ErrorMessage("The amount must be a number between 30 and 600 seconds."); } if (game.state !== "signups") throw new Chat.ErrorMessage("The game of UNO has already started."); if (game.autostartTimer) clearTimeout(game.autostartTimer); game.autostartTimer = setTimeout(() => { game.onStart(true); }, amount * 1e3); this.addModAction(`${user.name} has set the UNO autostart timer to ${amount} seconds.`); }, dq: "disqualify", disqualify(target, room, user) { room = this.requireRoom(); this.checkCan("minigame", null, room); const game = this.requireGame(UNO); const disqualified = game.eliminate(toID(target)); if (disqualified === false) throw new Chat.ErrorMessage(`Unable to disqualify ${target}.`); this.privateModAction(`${user.name} has disqualified ${disqualified} from the UNO game.`); this.modlog("UNO DQ", toID(target)); room.add(`${disqualified} has been disqualified from the UNO game.`).update(); }, // player/user commands j: "join", join(target, room, user) { const game = this.requireGame(UNO); this.checkChat(); if (!game.joinGame(user)) throw new Chat.ErrorMessage("Unable to join the game."); return this.sendReply("You have joined the game of UNO."); }, l: "leave", leave(target, room, user) { const game = this.requireGame(UNO); if (!game.leaveGame(user)) throw new Chat.ErrorMessage("Unable to leave the game."); return this.sendReply("You have left the game of UNO."); }, play(target, room, user) { const game = this.requireGame(UNO); if (!game) throw new Chat.ErrorMessage("There is no UNO game going on in this room right now."); const player = game.playerTable[user.id]; if (!player) throw new Chat.ErrorMessage(`You are not in the game of UNO.`); const error = game.onPlay(player, target); if (typeof error === "string") throw new Chat.ErrorMessage(error); }, draw(target, room, user) { room = this.requireRoom(); const game = room.getGame(UNO); if (!game) throw new Chat.ErrorMessage("There is no UNO game going on in this room right now."); const player = game.playerTable[user.id]; if (!player) throw new Chat.ErrorMessage(`You are not in the game of UNO.`); const error = game.onDraw(player); if (error) throw new Chat.ErrorMessage("You have already drawn a card this turn."); }, pass(target, room, user) { const game = this.requireGame(UNO); if (!game) throw new Chat.ErrorMessage("There is no UNO game going on in this room right now."); if (game.currentPlayerid !== user.id) throw new Chat.ErrorMessage("It is currently not your turn."); const player = game.playerTable[user.id]; if (!player) throw new Chat.ErrorMessage(`You are not in the game of UNO.`); if (!player.cardLock) throw new Chat.ErrorMessage("You cannot pass until you draw a card."); if (game.state === "color") throw new Chat.ErrorMessage("You cannot pass until you choose a color."); game.sendToRoom(`|c:|${Math.floor(Date.now() / 1e3)}|&|${user.name} has passed.`); game.nextTurn(); }, color(target, room, user) { const game = this.requireGame(UNO); const player = game.playerTable[user.id]; if (!player) throw new Chat.ErrorMessage(`You are not in the game of UNO.`); let color; if (target === "Red" || target === "Green" || target === "Blue" || target === "Yellow" || target === "Black") { color = target; } else { throw new Chat.ErrorMessage(`"${target}" is not a valid color.`); } game.onSelectColor(player, color); }, uno(target, room, user) { const game = this.requireGame(UNO); const player = game.playerTable[user.id]; if (!player) throw new Chat.ErrorMessage(`You are not in the game of UNO.`); game.onUno(player, toID(target)); }, // information commands "": "hand", hand(target, room, user) { const game = this.requireGame(UNO); game.onSendHand(user); }, "c": "cards", cards(target, room, user) { const game = this.requireGame(UNO); if (!this.runBroadcast()) return false; const players = `Players (${game.playerCount}):

${game.getPlayers(true)}`; this.sendReplyBox(`
${players}
`); }, players: "getusers", users: "getusers", getplayers: "getusers", getusers(target, room, user) { const game = this.requireGame(UNO); if (!this.runBroadcast()) return false; this.sendReplyBox(`Players (${game.playerCount}):${game.getPlayers()}`); }, help(target, room, user) { this.parse("/help uno"); }, // suppression commands suppress(target, room, user) { room = this.requireRoom(); const game = this.requireGame(UNO); this.checkCan("minigame", null, room); target = toID(target); const state = target === "on" ? true : target === "off" ? false : void 0; if (state === void 0) { return this.sendReply(`Suppression of UNO game messages is currently ${game.suppressMessages ? "on" : "off"}.`); } if (state === game.suppressMessages) { throw new Chat.ErrorMessage(`Suppression of UNO game messages is already ${game.suppressMessages ? "on" : "off"}.`); } game.suppressMessages = state; this.addModAction(`${user.name} has turned ${state ? "on" : "off"} suppression of UNO game messages.`); this.modlog("UNO SUPRESS", null, state ? "ON" : "OFF"); }, spectate(target, room, user) { const game = this.requireGame(UNO); if (!game) throw new Chat.ErrorMessage("There is no UNO game going on in this room right now."); if (!game.suppressMessages) throw new Chat.ErrorMessage("The current UNO game is not suppressing messages."); if (user.id in game.spectators) throw new Chat.ErrorMessage("You are already spectating this game."); game.spectators[user.id] = 1; this.sendReply("You are now spectating this private UNO game."); }, unspectate(target, room, user) { const game = this.requireGame(UNO); if (!game) throw new Chat.ErrorMessage("There is no UNO game going on in this room right now."); if (!game.suppressMessages) throw new Chat.ErrorMessage("The current UNO game is not suppressing messages."); if (!(user.id in game.spectators)) throw new Chat.ErrorMessage("You are currently not spectating this game."); delete game.spectators[user.id]; this.sendReply("You are no longer spectating this private UNO game."); } }, unohelp: [ `/uno create [player cap] - creates a new UNO game with an optional player cap (default player cap at 12). Use the command [createpublic] to force a public game or [createprivate] to force a private game. Requires: % @ # &`, `/uno setcap [player cap] - adjusts the player cap of the current UNO game. Requires: % @ # &`, `/uno timer [amount] - sets an auto disqualification timer for [amount] seconds. Requires: % @ # &`, `/uno autostart [amount] - sets an auto starting timer for [amount] seconds. Requires: % @ # &`, `/uno end - ends the current game of UNO. Requires: % @ # &`, `/uno start - starts the current game of UNO. Requires: % @ # &`, `/uno disqualify [player] - disqualifies the player from the game. Requires: % @ # &`, `/uno hand - displays your own hand.`, `/uno cards - displays the number of cards for each player.`, `/uno getusers - displays the players still in the game.`, `/uno [spectate|unspectate] - spectate / unspectate the current private UNO game.`, `/uno suppress [on|off] - Toggles suppression of game messages.` ] }; const roomSettings = (room) => ({ label: "UNO", permission: "editroom", options: [ [`disabled`, room.settings.unoDisabled || "uno disable"], [`enabled`, !room.settings.unoDisabled || "uno enable"] ] }); //# sourceMappingURL=uno.js.map