Guest User

Untitled

a guest
Jun 18th, 2016
93
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 22.49 KB | None | 0 0
  1. /*
  2. UNO Game for PS
  3.  
  4. by sparkychild
  5. */
  6. 'use strict';
  7. const deck = ["R1",
  8. "R2",
  9. "R3",
  10. "R4",
  11. "R5",
  12. "R6",
  13. "R7",
  14. "R8",
  15. "R9",
  16. "RS",
  17. "RR",
  18. "R+2",
  19. "Z+4",
  20. "Y1",
  21. "Y2",
  22. "Y3",
  23. "Y4",
  24. "Y5",
  25. "Y6",
  26. "Y7",
  27. "Y8",
  28. "Y9",
  29. "YS",
  30. "YR",
  31. "Y+2",
  32. "Z+4",
  33. "G1",
  34. "G2",
  35. "G3",
  36. "G4",
  37. "G5",
  38. "G6",
  39. "G7",
  40. "G8",
  41. "G9",
  42. "GS",
  43. "GR",
  44. "G+2",
  45. "Z+4",
  46. "B1",
  47. "B2",
  48. "B3",
  49. "B4",
  50. "B5",
  51. "B6",
  52. "B7",
  53. "B8",
  54. "B9",
  55. "BS",
  56. "BR",
  57. "B+2",
  58. "Z+4",
  59. "R1",
  60. "R2",
  61. "R3",
  62. "R4",
  63. "R5",
  64. "R6",
  65. "R7",
  66. "R8",
  67. "R9",
  68. "RS",
  69. "RR",
  70. "R+2",
  71. "ZW",
  72. "R0",
  73. "Y1",
  74. "Y2",
  75. "Y3",
  76. "Y4",
  77. "Y5",
  78. "Y6",
  79. "Y7",
  80. "Y8",
  81. "Y9",
  82. "YS",
  83. "YR",
  84. "Y+2",
  85. "ZW",
  86. "Y0",
  87. "G1",
  88. "G2",
  89. "G3",
  90. "G4",
  91. "G5",
  92. "G6",
  93. "G7",
  94. "G8",
  95. "G9",
  96. "GS",
  97. "GR",
  98. "G+2",
  99. "ZW",
  100. "G0",
  101. "B1",
  102. "B2",
  103. "B3",
  104. "B4",
  105. "B5",
  106. "B6",
  107. "B7",
  108. "B8",
  109. "B9",
  110. "BS",
  111. "BR",
  112. "B+2",
  113. "ZW",
  114. "B0",
  115. ];
  116. //declare html for DRAW and PASS button.
  117. const drawButton = '<center><button style="background: black; border: 2px solid rgba(33 , 68 , 72 , 0.59) ; width: 56px ; border-radius: 5px , auto" name="send" value="/uno draw"><font color="white">Draw</font></button></center>';
  118. const passButton = '<center><button style="background: red; border: 2px solid rgba(33 , 68 , 72 , 0.59) ; width: 56px ; border-radius: 5px , auto" name="send" value="/uno pass"><font color="white">PASS</font></button></center>';
  119.  
  120. //get colour for html'd text and backgrounds
  121. function getColour(colour, background) {
  122. if (!background && colour === "Y") return "orange";
  123. let colourTable = {
  124. "R": "red",
  125. "Y": "yellow",
  126. "B": "blue",
  127. "G": "green",
  128. "Z": "black",
  129. };
  130. return colourTable[colour];
  131. }
  132.  
  133. //build html button for the card
  134. function buildCard(id, notClickable) {
  135. let colour = getColour(id.charAt(0), true);
  136. let value = id.slice(1);
  137. let fontColour = colour === "yellow" ? "black" : "white";
  138. let command = "/uno play " + id;
  139. let clickable = notClickable ? ">" : "name=\"send\" value=\"" + command + "\">";
  140. let title = "title=\"" + getCardName(id) + "\"";
  141. let buttonFace = value === "W" ? '<img src="https://www.script-tutorials.com/demos/317/thumb.png" height="27" width="27">' : '<font color="' + fontColour + "\" size=6>" + value + "</font>";
  142. let button = "<button " + title + " style=\"background: " + colour + "; border: 2px solid rgba(33 , 68 , 72 , 0.59) ; height: 80px ; width: 56px ; border-radius: 5px , auto\"" + clickable + buttonFace + "</button>";
  143. return button;
  144. }
  145.  
  146. //build an display of multiple cards
  147. function buildHand(array, notClickable) {
  148. let hand = [];
  149. array.sort().forEach(function (c) {
  150. hand.push(buildCard(c, notClickable));
  151. });
  152. return hand.join("&nbsp;");
  153. }
  154.  
  155.  
  156. function initDeck(playerCount) {
  157. playerCount = Math.ceil(playerCount / 7);
  158. let tDeck = [];
  159. for (let i = 0; i < playerCount; i++) {
  160. tDeck = tDeck.concat(deck);
  161. }
  162. return tDeck;
  163. }
  164.  
  165. function shuffleDeck(dArray) {
  166. let tDeck = [];
  167. let reiterations = dArray.length;
  168. for (let i = 0; i < reiterations; i++) {
  169. let rand = ~~(dArray.length * Math.random());
  170. tDeck.push(dArray[rand]);
  171. dArray.splice(rand, 1);
  172. }
  173. return tDeck;
  174. }
  175.  
  176. function getCardName(id, colour) {
  177. let type = {
  178. "R": "Red",
  179. "Y": "Yellow",
  180. "B": "Blue",
  181. "G": "Green",
  182. "Z": "Wild",
  183. };
  184. let value = {
  185. "1": " 1",
  186. "2": " 2",
  187. "3": " 3",
  188. "4": " 4",
  189. "5": " 5",
  190. "6": " 6",
  191. "7": " 7",
  192. "8": " 8",
  193. "9": " 9",
  194. "0": " 0",
  195. "R": " Reverse",
  196. "S": " Skip",
  197. "+2": " Draw Two",
  198. "+4": " Draw Four",
  199. "W": "card",
  200. };
  201. if (colour) return "<font color=\"" + type[id.charAt(0)].toLowerCase().replace("yellow", "orange") + "\">" + type[id.charAt(0)] + value[id.slice(1)] + "</font>";
  202. return type[id.charAt(0)] + value[id.slice(1)];
  203. }
  204.  
  205.  
  206. function buildGameScreen(uhtmlid, top, roomid, hand, message, change, pass) {
  207. let html = (message ? "|uhtmlchange|" + uhtmlid : "|uhtml|" + uhtmlid) + "|";
  208. //make top card not clickable
  209. let topCard = "<center>" + buildCard(top, true) + "</center>";
  210. if (change) {
  211. topCard += "<br><center>Colour changed to: <font color=\"" + getColour(change) + "\">" + getColour(change, true) + "</font></center>";
  212. }
  213. let yourHand = buildHand(hand);
  214. message = message ? "<font color=\"red\"><b>" + message + "</b></font>" : "";
  215. return html + "<table border=1 style=\"border-collapse: collapse;\"><tr><td>&nbsp;<b>Top Card</b>&nbsp;</td><td>&nbsp;<b>Your Hand</b>&nbsp;</td></tr>" + "<tr><td>" + topCard + "</td><td>" + yourHand + "</td></tr><tr><td>" + (pass ? passButton : drawButton) + "</td><td>" + message + "</td></tr></table>";
  216. }
  217.  
  218. //for wildcards that summon a colour change
  219. function getColourChange(buffer, hand, uhtmlid) {
  220. return "|uhtmlchange|" + uhtmlid + "|<table border=1 style=\"border-collapse: collapse;\"><tr><td>Choose which colour to change to:<br>" + '<button style="background: red; border: 2px solid rgba(33 , 68 , 72 , 0.59) ; width: 80px ; border-radius: 5px , auto" name="send" value="' + buffer + ' R"><font color="white" size=4>Red</font></button></center>' + '<button style="background: yellow; border: 2px solid rgba(33 , 68 , 72 , 0.59) ; width: 80px ; border-radius: 5px , auto" name="send" value="' + buffer + ' Y"><font color="black" size=4>Yellow</font></button></center>' + '<button style="background: blue; border: 2px solid rgba(33 , 68 , 72 , 0.59) ; width: 80px ; border-radius: 5px , auto" name="send" value="' + buffer + ' B"><font color="white" size=4>Blue</font></button></center>' + '<button style="background: green; border: 2px solid rgba(33 , 68 , 72 , 0.59) ; width: 80px ; border-radius: 5px , auto" name="send" value="' + buffer + ' G"><font color="white" size=4>Green</font></button></td></tr>' + '<tr><td>Your Cards: <br>' + buildHand(hand, true) + '</td></tr></table>';
  221. }
  222.  
  223. function getUserName(id) {
  224. return Users(id) ? Users(id).name : id;
  225. }
  226.  
  227. class Game {
  228. constructor(room, playerCap) {
  229. if (!room.unoGameId) {
  230. room.unoGameId = 0;
  231. }
  232. room.unoGameId++;
  233. this.room = room;
  234. this.id = 0;
  235. this.top = null;
  236. this.discard = [];
  237. this.deck = null;
  238. //for player order
  239. this.list = [];
  240. this.data = {};
  241. this.joinedIps = {};
  242. this.player = null;
  243. this.gameid = "uno";
  244. this.started = false;
  245. this.timer = null;
  246. this.lastDraw = null;
  247. this.colourChange = null;
  248. this.uhtmlChange = null;
  249. this.playerCap = playerCap ? playerCap : null;
  250. }
  251.  
  252. init() {
  253. this.room.add("|uhtml|new" + this.room.unoGameId + "|<div class=\"broadcast-black\"><center><img src=\"http://www.theboardgamefamily.com/wp-content/uploads/2010/12/uno-mobile-game1.jpg\" height=150 width=160><br><font color=white><b>A new game of UNO is starting</b></font><br><br><button style=\"height: 25px ; width: 50px ;\" name=\"send\" value=\"/uno join\">Join</button></center></div>");
  254. }
  255.  
  256. join(user) {
  257. if (this.started) return false;
  258. let ip = user.latestIp;
  259. let userid = user.userid;
  260.  
  261. if (this.playerCap && this.list.length >= this.playerCap) {
  262. return user.sendTo(this.room, "The game is already full.");
  263. }
  264.  
  265. if (userid in this.data || ip in this.joinedIps) {
  266. return user.sendTo(this.room, "You already have an alt joined.");
  267. }
  268.  
  269. this.list.push(userid);
  270. //init empty hand
  271. this.data[userid] = [];
  272. this.joinedIps[ip] = 1;
  273. //make join messages clear away after game starts
  274. this.room.add("|uhtml|init" + this.room.unoGameId + "|" + user.name + " has joined the game.");
  275. }
  276.  
  277. start(user) {
  278. if (this.started) return false;
  279. if (this.list.length < 2) return user.sendTo(this.room, "There aren't enough players!");
  280. this.started = true;
  281. this.room.add("The game has started!");
  282. //hide the start message
  283. this.room.add("|uhtmlchange|new" + this.room.unoGameId + "|<div class=\"infobox\">The game has started.</div>");
  284. //get first player
  285. this.player = this.list[~~(Math.random() * this.list.length)];
  286. this.room.add("The first player is: " + getUserName(this.player) + ".");
  287.  
  288. //create the deck
  289. this.deck = shuffleDeck(initDeck(this.list.length));
  290.  
  291. //deal the cards
  292. this.list.forEach(function (u) {
  293. this.giveCard(u, 7);
  294. }.bind(this));
  295.  
  296. //get the top card and put it into discard pile
  297. while (!this.top || this.top.charAt(0) === "Z") {
  298. this.top = this.deck.shift();
  299. this.discard.push(this.top);
  300. }
  301. //declare the top card
  302. this.room.add("|uhtml|" + this.room.unoGameId + "card" + this.id + "|" + "The top card is " + buildCard(this.top, true));
  303. this.uhtmlChange = "|uhtmlchange|" + this.room.unoGameId + "card" + this.id + "|The top card is <b>" + getCardName(this.top, true) + "</b>.";
  304.  
  305. this.applyEffects();
  306.  
  307. this.initNextTurn();
  308. }
  309.  
  310. giveCard(userid, number, display) {
  311. if (!number) number = 1;
  312. let newCards = [];
  313. for (let i = 0; i < number; i++) {
  314. let newCard = this.deck.shift();
  315. this.data[userid].push(newCard);
  316. newCards.push(newCard);
  317. //shuffle deck if deck is empty
  318. if (this.deck.length === 0) {
  319. if (this.discard.length === 0) {
  320. //if no cards in discard pile, add a new deck.
  321. this.discard = initDeck(1);
  322. }
  323. //shuffle discard pile to create new deck for drawing
  324. this.deck = shuffleDeck(this.discard);
  325. }
  326. }
  327. if (display && Users(userid)) {
  328. return Users(userid).sendTo(this.room, "|raw|You have drawn the following card(s): " + buildHand(newCards, true));
  329. }
  330. //only for draw 1
  331. if (newCards.length === 1) return newCards[0];
  332. }
  333.  
  334. getNextPlayer(number) {
  335. //make list run over if it's at the last player
  336. let playerList = this.list.concat(this.list);
  337. //get index of current player
  338. let index = playerList.indexOf(this.player);
  339. //apply next player
  340. this.player = playerList[index + (number || 1)];
  341. }
  342.  
  343. applyEffects() {
  344. let effect = this.top.slice(1);
  345. switch (effect) {
  346. case "R":
  347. //reverse; turn the array of players upside down.
  348. this.list = this.list.reverse();
  349. this.room.add("The direction has been reversed!");
  350. if (this.id === 0) {
  351. this.getNextPlayer();
  352. break;
  353. } else if (this.list.length === 2) {
  354. //skip back to the player that played the card
  355. this.getNextPlayer();
  356. } else {
  357. //skip back two slots to the player before the user who played the card
  358. this.getNextPlayer(2);
  359. }
  360. break;
  361. case "S":
  362. this.room.add(getUserName(this.player) + " has turn has been skipped!");
  363. //skip the player and move on to the next;
  364. this.getNextPlayer();
  365. break;
  366. case "+2":
  367. this.room.add(getUserName(this.player) + " has turn has been skipped, and is forced to draw 2 cards!");
  368. //give 2 cards
  369. this.giveCard(this.player, 2, true);
  370. //skip the player
  371. this.getNextPlayer();
  372. break;
  373. case "+4":
  374. this.room.add(getUserName(this.player) + " has turn has been skipped, and is forced to draw 4 cards!");
  375. //give 4 cards
  376. this.giveCard(this.player, 4, true);
  377. //skip the player
  378. this.getNextPlayer();
  379. break;
  380. }
  381. }
  382.  
  383. validatePlay(user, card) {
  384. //returning false means there are no issues;
  385. //otherwise this will return a error message which will be displayed to the user when it builds the next control screen.
  386. let hand = this.data[user.userid];
  387. if (this.lastDraw && card !== this.lastDraw) {
  388. return "You must play the last card you drew! (" + getCardName(this.lastDraw) + ")";
  389. }
  390. if (hand.indexOf(card) === -1) return "You do not have that card!";
  391. let currentColour = this.colourChange || this.top.charAt(0);
  392. let currentValue = this.top.slice(1);
  393. //verify that the player has no cards of the same colour in their hand
  394. if (card === "Z+4") {
  395. for (let i = 0; i < hand.length; i++) {
  396. if (hand[i].charAt(0) === currentColour) return "You cannot play this when you still have a card with the same colour as the top card.";
  397. }
  398. return false;
  399. }
  400. //wild cards can be played anytime
  401. if (card === "ZW") return false;
  402. //check if the card is either the same value or the same colour
  403. if (card.charAt(0) === currentColour || card.slice(1) === currentValue) return false;
  404. return "The card has to either match the top card's colour or face value.";
  405. }
  406.  
  407. play(user, card, change) {
  408. //check if it's that players turn
  409. if (this.player !== user.userid) return;
  410. //check validity of play and send error message
  411. let issues = this.validatePlay(user, card);
  412. if (issues) {
  413. return this.sendGameScreen(user, issues);
  414. }
  415. this.colourChange = null;
  416. this.clearTimer();
  417. //shrink last turn's card
  418. this.room.add(this.uhtmlChange);
  419. this.clearGameScreen(user);
  420.  
  421. //clear last draw
  422. this.lastDraw = null;
  423.  
  424. //announce the card and the change
  425. this.room.add("|uhtml|" + this.room.unoGameId + "card" + this.id + "|" + user.name + " played " + buildCard(card, true));
  426. this.uhtmlChange = "|uhtmlchange|" + this.room.unoGameId + "card" + this.id + "|" + user.name + " played <b>" + getCardName(card, true) + "</b>.";
  427.  
  428. //move card onto top and discard pile
  429. this.top = card;
  430. this.discard.push(card);
  431.  
  432. //remove the card from the players hand
  433. this.data[user.userid].splice(this.data[user.userid].indexOf(card), 1);
  434.  
  435. //count cards
  436. if (change) {
  437. this.colourChange = change;
  438. let fontColour = getColour(change);
  439. this.room.add("|raw|<font color=\"" + fontColour + "\">The colour was changed to <b>" + getColour(change, true).toUpperCase() + "</b>.</font>");
  440. }
  441. //move to next player
  442. this.getNextPlayer();
  443. this.room.update();
  444.  
  445. //apply the effects of the current card to the next player in queue.
  446. this.applyEffects();
  447. if (this.data[user.userid].length === 1) {
  448. //do a uno thing
  449. this.uno = user.userid;
  450. let userButton = "<center><button style=\"height: 75px ; width: 200px ;\" name=\"send\" value=\"/uno uno\">UNO!</button></center>";
  451. user.sendTo(this.room.id, "|uhtml|" + this.room.unoGameId + "uno" + this.id + "|" + userButton);
  452. //send individual button to all the other players
  453. let opponentButton = "<center><button style=\"height: 75px ; width: 200px ;\" name=\"send\" value=\"/uno uno\">Make " + user.name + " draw 2 cards! </button></center>";
  454. for (let u in this.data) {
  455. if (!Users(u) || u === user.userid) continue;
  456. Users(u).sendTo(this.room.id, "|uhtml|" + this.room.unoGameId + "uno" + this.id + "|" + opponentButton);
  457. }
  458. return;
  459. } else if (this.data[user.userid].length === 0) {
  460. return this.end(user.name);
  461. }
  462. //start next turn
  463. this.initNextTurn();
  464. }
  465.  
  466. draw(user) {
  467. if (this.player !== user.userid || this.lastDraw) return;
  468. this.lastDraw = this.giveCard(user.userid, 1);
  469. //clean up last display
  470. this.clearGameScreen(user);
  471. this.sendGameScreen(user, "You have drawn a " + getCardName(this.lastDraw) + ".");
  472. this.room.add(user.name + " has drawn a card.");
  473. this.room.update();
  474. }
  475.  
  476. pass(user) {
  477. if (this.player !== user.userid || !this.lastDraw) return;
  478. this.room.add(user.name + " has passed.");
  479. this.room.add(this.uhtmlChange);
  480. this.clearGameScreen(user);
  481. this.clearTimer();
  482. this.getNextPlayer();
  483. this.id++;
  484. this.lastDraw = null;
  485. this.initNextTurn();
  486. }
  487.  
  488. sendGameScreen(user, message) {
  489. let display = buildGameScreen(this.room.unoGameId + "display" + this.id, this.top, this.room.id, this.data[user.userid], message ? message : "", this.colourChange, this.lastDraw ? 1 : 0);
  490. user.sendTo(this.room, display);
  491. }
  492.  
  493. clearGameScreen(user) {
  494. user.sendTo(this.room, "|uhtmlchange|" + this.room.unoGameId + "display" + this.id + "|");
  495. }
  496.  
  497. clearTimer() {
  498. clearTimeout(this.timer);
  499. }
  500.  
  501. runDQ() {
  502. //set a disqualification timer for 90 seconds
  503. this.timer = setTimeout(function () {
  504. this.disqualify(this.player);
  505. }.bind(this), 90000);
  506. }
  507.  
  508. initNextTurn() {
  509. this.room.add(getUserName(this.player) + "'s turn.");
  510. this.room.update();
  511. this.id++;
  512. let user = Users.get(this.player);
  513. if (!user) this.disqualify(this.player);
  514. this.sendGameScreen(user);
  515. this.runDQ();
  516. }
  517.  
  518. disqualify(userid) {
  519. //if there are still players in the game.
  520. if (this.list.length > 2) {
  521. //if current player is the one being disqualify move on to next player.
  522. if (!this.removePlayer(userid)) return true;
  523. if (userid === this.player) {
  524. if (Users.get(userid)) {
  525. this.clearGameScreen(Users.get(userid));
  526. this.room.add(this.uhtmlChange);
  527. }
  528. this.clearTimer();
  529. this.room.add(getUserName(userid) + " has been disqualified.");
  530. this.getNextPlayer();
  531. this.initNextTurn();
  532. return true;
  533. }
  534. this.room.add(getUserName(userid) + " has been disqualified.");
  535. return true;
  536. } else {
  537. if (this.removePlayer(userid)) {
  538. this.room.add(getUserName(userid) + " has been disqualified.");
  539. this.end(this.list[0]);
  540. return false;
  541. }
  542. }
  543. }
  544.  
  545. removePlayer(userid) {
  546. if (this.list.indexOf(userid) === -1) return false;
  547. this.list.splice(this.list.indexOf(userid), 1);
  548. delete this.data[userid];
  549. return true;
  550. }
  551.  
  552. parseUNO(user) {
  553. if (!this.uno) return false;
  554. if (user.userid === this.uno) {
  555. this.room.add("|raw|<b>UNO!</b>");
  556. this.room.add("|uhtmlchange|" + this.room.unoGameId + "uno" + this.id + "|" + getUserName(this.uno) + " is safe!");
  557. this.room.update();
  558. this.uno = false;
  559. this.initNextTurn();
  560. } else if (this.list.indexOf(user.userid) > -1) {
  561. this.room.add("|raw|" + getUserName(this.uno) + " was caught for not saying UNO and is forced to draw 2 cards!");
  562. this.room.add("|uhtmlchange|" + this.room.unoGameId + "uno" + this.id + "|" + getUserName(this.uno) + " was caught!");
  563. this.giveCard(this.uno, 2, true);
  564. this.uno = false;
  565. this.initNextTurn();
  566. }
  567. }
  568.  
  569. end(winner) {
  570. //hide the start message
  571. this.clearTimer();
  572. if (this.player && Users.get(this.player)) {
  573. this.clearGameScreen(Users.get(this.player));
  574. }
  575. if (this.uhtmlChange) this.room.add(this.uhtmlChange);
  576. this.room.add("|uhtmlchange|new" + this.room.unoGameId + "|<div class=\"infobox\">The game has ended.</div>");
  577. if (!winner) {
  578. this.room.add("The game of UNO was forcibly ended.");
  579. } else {
  580. this.room.add("Congratulations to " + getUserName(winner) + " for winning the game of UNO!");
  581. }
  582. this.room.update();
  583. delete this.room.game;
  584. }
  585. }
  586.  
  587. exports.commands = {
  588. uno: {
  589. new: function (target, room, user) {
  590. if (!this.can("announce", null, room)) return false;
  591. if (room.unoDisabled) return this.errorReply("UNO is currently disabled in this room.");
  592. let cap = target ? parseInt(target, 10) : null;
  593. if (room.game) return this.errorReply("There is already a game in progress in this room.");
  594. if (cap && cap < 2) return this.errorReply("The player cap has to be at least 2.");
  595.  
  596. room.game = new Game(room, cap);
  597. //start message;
  598. room.game.init();
  599. },
  600. join: function (target, room, user) {
  601. if (room.game && room.game.gameid === "uno") room.game.join(user);
  602. },
  603. start: function (target, room, user) {
  604. if (!this.can("announce", null, room)) return false;
  605. if (room.game && room.game.gameid === "uno") room.game.start(user);
  606. },
  607. end: function (target, room, user) {
  608. if (!this.can("announce", null, room)) return false;
  609. if (room.game && room.game.gameid === "uno") room.game.end();
  610. },
  611. leave: function (target, room, user) {
  612. if (room.game && room.game.gameid === "uno" && !room.game.started) {
  613. let success = room.game.removePlayer(user.userid);
  614. if (!success) return user.sendTo(this.room, "You have not signed up for the game.");
  615. let ip = user.latestIp;
  616. delete room.game.joinedIps[ip];
  617. room.add("|uhtml|init" + room.unoGameId + "|" + user.name + " has left the game.");
  618. }
  619. },
  620. play: function (target, room, user) {
  621. if (!room.game || room.game.gameid !== "uno") return false;
  622. if (!target) return this.parse("/help uno play");
  623. let params = target.split(" ");
  624. let card = params.shift();
  625. let change = null;
  626. if (card.charAt(0) === "Z" && ["R", "Y", "B", "G"].indexOf(params[0]) > -1) {
  627. change = params[0];
  628. } else if (card.charAt(0) === "Z") {
  629. let uhtmlid = room.unoGameId + "display" + room.game.id;
  630. return user.sendTo(room, getColourChange("/uno play " + card, room.game.data[user.userid], uhtmlid));
  631. }
  632. room.game.play(user, card, change);
  633. },
  634. draw: function (target, room, user) {
  635. if (room.game && room.game.gameid === "uno") room.game.draw(user);
  636. },
  637. pass: function (target, room, user) {
  638. if (room.game && room.game.gameid === "uno") room.game.pass(user);
  639. },
  640. dq: function (target, room, user) {
  641. if (!this.can("announce", null, room)) return false;
  642. if (!target) return this.parse("/help uno dq");
  643. if (room.game && room.game.gameid === "uno") room.game.disqualify(toId(target));
  644. },
  645. dqhelp: ["/uno dq [user] - disqualifies a user from the game."],
  646. display: function (target, room, user) {
  647. if (!room.game || room.game.gameid !== "uno" || user.userid !== room.game.player) return false;
  648. room.game.clearGameScreen(user);
  649. room.game.id++;
  650. room.game.sendGameScreen(user);
  651. },
  652. uno: function (target, room, user) {
  653. if (room.game && room.game.gameid === "uno" && room.game.started) {
  654. room.game.parseUNO(user);
  655. }
  656. },
  657. enable: function (target, room, user) {
  658. if (!this.can('tournamentsmanagement', null, room)) return;
  659. if (!room.unoDisabled) return this.errorReply("UNO is not disabled in this room.");
  660. delete room.unoDisabled;
  661. if (room.chatRoomData) {
  662. delete room.chatRoomData.unoDisabled;
  663. Rooms.global.writeChatRoomData();
  664. }
  665. return this.sendReply("UNO has been enabled for this room.");
  666. },
  667. disable: function (target, room, user) {
  668. if (!this.can('tournamentsmanagement', null, room)) return;
  669. if (room.unoDisabled) return this.errorReply("UNO is already disabled in this room.");
  670. room.unoDisabled = true;
  671. if (room.chatRoomData) {
  672. room.chatRoomData.unoDisabled = true;
  673. Rooms.global.writeChatRoomData();
  674. }
  675. return this.sendReply("UNO has been disabled for this room.");
  676. },
  677. "": function (target, room, user) {
  678. if (!room.game || room.game.gameid !== "uno" || user.userid !== room.game.player) return this.parse("/help uno");
  679. this.parse("/uno display");
  680. },
  681. },
  682. unohelp: [
  683. "/uno new (player cap) - starts a new uno game with an optional player cap.",
  684. "/uno join - joins the current game of UNO.",
  685. "/uno leave - leaves the current game of UNO.",
  686. "/uno start - starts the current game of UNO",
  687. "/uno play [card id] [change] - plays the uno card and specifies colour change if applicable.",
  688. "/uno draw - draws a card.",
  689. "/uno pass - pass after drawing a card.",
  690. "/uno uno - call out \"UNO!\" or attempt to catch someone for not saying uno.",
  691. "/uno enable - enables UNO in that room.",
  692. "/uno disable - disables UNO in that room.",
  693. ],
  694. };
Add Comment
Please, Sign In to add comment