class ServerEventsHandlers { constructor(game) { this.game = game; } version(data) { const servVersion = data[0]; if(servVersion == REVISION) { return; } alert(strings["bad_version"]); this.game.conn.close(); this.game.conn = null; } err(data) { alert(strings[data[0]]); this.game.conn.close(); this.game.conn = null; } exploded(data) { const nickname = data[0]; this.game.console("<span class=\"text-primary\">" + nickname + " drew a Detonating Cat!</span>"); cardHUD("exploding", 1000); } // Legacy ?? card_left(data) { $("#remaining-card-count").text(data[0]); } now_playing(data) { this.game.nowPlaying = data[0]; this.game.console("<span class=\"text-info\">It is " + this.game.nowPlaying + "'s turn.</span>"); this.game.drawPlayerList(); // cmp with raw data because name isn't stored encoded if (data[0] == this.game.name) { this.game.ourTurn = true; this.game.assets["atomic.ogg"].play(); document.title = strings["title_alert"]; $(".bottom-notify-container").html(strings["your_turn"]); } else { this.game.ourTurn = false; document.title = strings["title_normal"]; // a bit fragile, needs to be same as <title> $(".bottom-notify-container").html(""); } } players(data) { // Update players list this.game.players = data; this.game.spectators = this.game.spectators.filter(i => !this.game.players.includes(i)); this.game.drawPlayerList(); this.game.drawSpectatorsList(); } spectators(data) { // Update spectators list this.game.spectators = data.filter(i => !this.game.players.includes(i)); this.game.drawSpectatorsList(); } joins(data) { const nickname = data[0]; if(nickname == this.game.name && !this.game.started) { return this.game.start(); } this.game.console("<span class=\"text-success\">" + nickname + " joined as a spectator.</span>"); this.game.addSpectator(nickname); } upgrades(data) { const nickname = data[0]; this.game.console("<span class=\"text-danger\">" + nickname + " is now spectating.</span>"); this.game.removeSpectator(nickname); } downgrades(data) { const nickname = data[0]; this.game.console("<span class=\"text-success\">" + nickname + " is now playing.</span>"); this.game.addSpectator(nickname); } parts(data) { const nickname = data[0]; this.game.console("<span class=\"text-danger\">" + nickname + " left the game.</span>"); this.game.removeSpectator(nickname); } chat(data) { const nickname = data[0]; const msg = data.join(" ").substring(nickname.length); this.game.console(`${nickname}: ${msg}`); } message(data) { // This refers to the 'message' container in the middle of the board // that can be used to display useful game info const msg = strings["message_" + data[0]]; $("#message").html(msg); $("#message-container").removeClass("reveal"); } clear_message(data) { $("#message").html(""); $("#message-container").addClass("reveal"); } bcast(data) { let msg = strings["bcast_" + data[0]]; this.game.console(msg); } hand(data) { this.game.hand = data; $("#card-deck").empty(); for (let i=0; i < this.game.hand.length; i++) { let card = $("<img class='card' src='assets/card_" + this.game.hand[i] + ".png' />"); (function (gameState, cardNo, cardName) { card.on("click", function() { if (gameState.locked) { return; } if (gameState.favouring) { // Favour NOPE-logic is handled server-side :) gameState.send("a favour_what "+cardNo.toString()); gameState.favouring = false; return; } if (gameState.combo > 1) { // Do we have enough cards? let cards = 0; for (var j=1; j < parts.length; j++) { if (parts[j] == cardName) { cards++; if (cards == gameState.combo) { break; } } } if (cards < gameState.combo) { gameState.console("You don't have enough " + strings["card_"+cardName] + " cards to do that!"); return; } if (gameState.ourTurn) { gameState.send("play_multiple "+gameState.combo.toString()+" "+ cardName); gameState.resetButtons(); return; } } if ((gameState.ourTurn || cardName === "nope") && !cardName.startsWith("random") && ( (!gameState.defusing && cardName !== "defuse") || (gameState.defusing && cardName === "defuse") )) { gameState.send("play "+cardNo.toString()); gameState.defusing = false; } }); })(this.game, i, this.game.hand[i]); $("#card-deck").append(card); } } draw_pile(data) { const flag = data[0] == "yes" ? true : false; if(flag) { $("#draw-pile").html("<img class='card' src='assets/card_back.png' />"); $("#draw-pile-counter").removeClass("reveal"); } else { $("#draw-pile").html(""); $("#draw-pile-counter").addClass("reveal"); } } drew(data) { this.game.console("You drew <span class=\"text-warning\">" + strings["card_" + data[0]] + ".</span>"); cardHUD(parts[1], 2000); } drew_other(data) { const nickname = data[0]; this.game.console("<span class=\"text-primary\">" + nickname + " drew a card.</span>"); // Animation $("#draw-pile-animation").html("<img src='assets/card_back.png' class='card' />"); animate("#draw-pile-animation", "right", 125, -150, -15, "px"); } wins(data) { const nickname = data[0]; this.game.ourTurn = false; this.game.console("<span class=\"text-primary\"><b>" + nickname + " won!</b></span>"); this.game.nowPlaying = ""; } defusing(data) { this.game.console(strings["must_defuse"]); this.game.defusing = true; } played(data) { const [ nickname, card ] = data; this.game.console(nickname + " played " + strings["card_" + card] + "."); $("#discard-pile").html("<img class='card' src='assets/card_" + card + ".png' />"); if (card != "see3") { cardHUD(card, 1000); } } played_multiple(data) { const [nickname, x, card] = data; this.game.console(nickname + " played " + x + "x " + strings["card_" + card] + "."); $("#discard-pile").html("<img class='card' src='assets/card_" + card + ".png' />"); if (x == 2) { cardHUD3([card, card], 1000); } else { cardHUD3([card, card, card], 1000); } } no_discard(data) { $("#discard-pile").html(""); } q(data) { const type = data[0]; if (type == "favour_what") { this.game.favouring = true; let perpetrator = data[1]; this.game.console("<span class=\"text-primary\">" + perpetrator + " is asking you for a favour.</span>"); } else if (type == "favour_who" || type == "random_who" || type == "steal_who") { (function (gameState) { modalChoice(function(player) { gameState.send("a " + type + " " + player); }, strings["question_" + type], gameState.players, entities(gameState.name), null); })(this.game); } else if (type == "steal_what") { (function (gameState) { modalChoice(function(card) { gameState.send("a " + type + " " + card); }, strings["question_" + type], cards, null, x => strings["card_" + x]); })(this.game); } else { ans = prompt(strings["question_" + type]); this.game.send("a " + type + " " + ans); } } q_cancel(data) { this.game.favouring = false; } seen(data) { cardHUD3(data, 2000); this.game.console("You saw " + strings["card_" + data[0]] + ", " + strings["card_" + data[1]] + " and " + strings["card_" + data[2]] + "."); } favoured(data) { const [ perpetrator, victim ] = data; this.game.console(perpetrator + " is asking " + victim + " for a favour."); } favour_complete(data) { const [ perpetrator, victim ] = data; this.game.console(victim + " gave " + perpetrator + " a favour."); } favour_recv(data) { const remotePlayer = data[0]; const card = strings["card_" + data[1]]; this.game.console(remotePlayer + " gave you <span class=\"text-info\">" + card + "</span>."); cardHUD(data[1], 2000); } favour_gave(data) { const remotePlayer = data[0]; const card = strings["card_" + data[1]]; this.game.console("You gave " + remotePlayer + " <span class=\"text-info\">" + card + "</span>."); } randomed(data) { const [ perpetrator, victim ] = data; this.game.console(perpetrator + " took a random card from " + victim + "."); } random_n(data) { const [ perpetrator, victim ] = data; this.game.console(perpetrator + " asked " + victim + " for a random card, but they had nothing to give away!"); } random_recv(data) { const remotePlayer = data[0]; const card = strings["card_" + data[1]]; this.game.console("You randomly took <span class=\"text-info\">" + card + "</span> from " + remotePlayer + "."); cardHUD(data[1], 2000); } random_gave(data) { const remotePlayer = data[0]; const card = strings["card_" + data[1]]; this.game.console(remotePlayer + " randomly took <span class=\"text-info\">" + card + "</span> from you."); cardHUD(data[1], 2000); } steal_n(data) { const [ perpetrator, victim, card ] = data; this.game.console(perpetrator + " asked " + victim + " for <span class=\"text-info\">" + strings["card_" + card] + "</span>, but ended up empty-handed!"); } steal_y(data) { const [ perpetrator, victim, card ] = data; this.game.console(perpetrator + " stole <span class=\"text-info\">" + strings["card_" + card]+"</span> from " + victim + "!"); cardHUD(card, 2000); } lock(data) { this.game.locked = true; } unlock(data) { this.game.locked = false; } }