Merge branch 'custom-role-saving' of https://github.com/AlecM33/Werewolf into custom-role-saving

This commit is contained in:
Alec Maier
2020-04-12 16:37:27 -04:00
7 changed files with 155 additions and 47 deletions

View File

@@ -58,6 +58,16 @@ server.listen(process.env.PORT || 5000, function() {
console.log('Starting server on port 5000'); console.log('Starting server on port 5000');
}); });
// If there are multiple dream wolves, convert them all.
function activateDreamWolvesIfNeeded(game) {
game.players.forEach((player) => {
if (!player.dead && player.card.role === "Dream Wolf") {
player.card.isTypeOfWerewolf = true;
console.log("player " + player.name + " was converted to a wolf!");
}
})
}
function teamWon(game) { function teamWon(game) {
let wolvesAlive = 0; let wolvesAlive = 0;
let villagersAlive = 0; let villagersAlive = 0;
@@ -80,7 +90,7 @@ function teamWon(game) {
if (wolvesAlive === 0) { if (wolvesAlive === 0) {
return "village" return "village"
} }
if ((wolvesAlive === villagersAlive) && (totalAlive !== 2)) { if ((wolvesAlive >= villagersAlive) && (totalAlive !== 2)) {
return "wolf"; return "wolf";
} }
if (totalAlive === 2) { if (totalAlive === 2) {
@@ -164,21 +174,28 @@ io.on('connection', function(socket) {
let game = activeGames[Object.keys(activeGames).find((key) => key === code)]; let game = activeGames[Object.keys(activeGames).find((key) => key === code)];
if (game) { if (game) {
let player = game.players.find((player) => player.id === id); let player = game.players.find((player) => player.id === id);
game.players.find((player) => player.id === id).dead = true; if (player) {
game.killedPlayer = player.name; player.dead = true;
game.lastKilled = player.id; player.deadAt = new Date().toJSON();
game.killedRole = player.card.role; game.killedPlayer = player.name;
game.message = player.name + ", a " + player.card.role + ", was killed!"; game.lastKilled = player.id;
console.log(game.message); game.killedRole = player.card.role;
const winCheck = teamWon(game); game.message = player.name + ", a " + player.card.role + ", was killed!";
if (winCheck === "wolf") { console.log(game.message);
console.log("wolves won the game!"); if (player.card.role === "Werewolf" && game.hasDreamWolf) {
game.winningTeam = "wolf"; activateDreamWolvesIfNeeded(game);
game.status = "ended"; }
} if (winCheck === "village") { const winCheck = teamWon(game);
console.log("village won the game!"); if (winCheck === "wolf") {
game.winningTeam = "village"; console.log("wolves won the game!");
game.status = "ended"; game.winningTeam = "wolf";
game.status = "ended";
}
if (winCheck === "village") {
console.log("village won the game!");
game.winningTeam = "village";
game.status = "ended";
}
} }
} }
}); });

View File

@@ -15,7 +15,7 @@ export let cards = [
role: "Dream Wolf", role: "Dream Wolf",
team: "evil", team: "evil",
description: "If a Werewolf dies, you become a Werewolf. You do not wake up with the Werewolves until this happens.", description: "If a Werewolf dies, you become a Werewolf. You do not wake up with the Werewolves until this happens.",
isTypeOfWerewolf: true isTypeOfWerewolf: false
}, },
{ {
role: "Minion", role: "Minion",

View File

@@ -18,18 +18,6 @@ socket.on('state', function(game) {
} }
}); });
window.onblur = function() { // pause animations if the window is not in focus
this.document.querySelector("#overlay").style.animationPlayState = 'paused';
this.document.querySelector("#killed-role").style.animationPlayState = 'paused';
this.document.querySelector("#killed-name").style.animationPlayState = 'paused';
};
window.onfocus = function() { // play animations when window is focused
this.document.querySelector("#overlay").style.animationPlayState = 'running';
this.document.querySelector("#killed-role").style.animationPlayState = 'running';
this.document.querySelector("#killed-name").style.animationPlayState = 'running';
};
function buildGameBasedOnState(game) { function buildGameBasedOnState(game) {
switch(game.status) { switch(game.status) {
case "lobby": case "lobby":
@@ -102,6 +90,7 @@ function playKilledAnimation() {
function launchGame() { function launchGame() {
randomlyDealCardsToPlayers(); randomlyDealCardsToPlayers();
utility.shuffle(currentGame.players); // put the players in a random order
socket.emit('startGame', { players: currentGame.players , code: currentGame.accessCode}); socket.emit('startGame', { players: currentGame.players , code: currentGame.accessCode});
} }
@@ -126,7 +115,8 @@ function getLiveCount() {
} }
function renderEndSplash() { function renderEndSplash() {
document.getElementById("game-container").classList.add("hidden"); clearInterval(clock);
document.getElementById("game-container").remove();
document.querySelector("#message-box").style.display = 'none'; document.querySelector("#message-box").style.display = 'none';
currentGame.winningTeam === "village" currentGame.winningTeam === "village"
? document.getElementById("end-container").innerHTML ="<div class='winner-header'><p class='winner-village'>Village</p> wins!</div>" ? document.getElementById("end-container").innerHTML ="<div class='winner-header'><p class='winner-village'>Village</p> wins!</div>"
@@ -149,6 +139,12 @@ function renderEndSplash() {
} }
function renderGame() { function renderGame() {
// remove lobby components if present
if (document.getElementById("lobby-container") !== null && document.getElementById("launch") !== null) {
document.getElementById("lobby-container").remove();
document.getElementById("launch").remove();
}
document.querySelector("#message-box").style.display = 'block'; document.querySelector("#message-box").style.display = 'block';
if (currentGame.killedRole && currentGame.lastKilled !== lastKilled) { // a new player has been killed if (currentGame.killedRole && currentGame.lastKilled !== lastKilled) { // a new player has been killed
lastKilled = currentGame.lastKilled; lastKilled = currentGame.lastKilled;
@@ -159,8 +155,6 @@ function renderGame() {
const player = currentGame.players.find((player) => player.id === sessionStorage.getItem("id")); const player = currentGame.players.find((player) => player.id === sessionStorage.getItem("id"));
// render the header // render the header
document.getElementById("lobby-container").setAttribute("class", "hidden");
document.getElementById("launch").setAttribute("class", "hidden");
document.getElementById("game-container").setAttribute("class", "game-container"); document.getElementById("game-container").setAttribute("class", "game-container");
const gameHeader = document.createElement("div"); const gameHeader = document.createElement("div");
gameHeader.setAttribute("id", "game-header"); gameHeader.setAttribute("id", "game-header");
@@ -169,9 +163,9 @@ function renderGame() {
"<div id='clock'></div>" + "<div id='clock'></div>" +
"<div id='pause-container'></div>"; "<div id='pause-container'></div>";
if (document.getElementById("game-header")) { if (document.getElementById("game-header")) {
document.getElementById("game-container").removeChild(document.getElementById("game-header")); document.getElementById("card-container").removeChild(document.getElementById("game-header"));
} }
document.getElementById("game-container").prepend(gameHeader); document.getElementById("card-container").prepend(gameHeader);
// render the card if it hasn't been yet // render the card if it hasn't been yet
if (!cardRendered) { if (!cardRendered) {
@@ -200,10 +194,63 @@ function renderGame() {
killedBtn.innerText = "I'm dead"; killedBtn.innerText = "I'm dead";
} }
if (document.getElementById("dead-btn")) { if (document.getElementById("dead-btn")) {
document.getElementById("game-container").removeChild(document.getElementById("dead-btn")); document.getElementById("card-container").removeChild(document.getElementById("dead-btn"));
} }
document.getElementById("game-container").appendChild(killedBtn); document.getElementById("card-container").appendChild(killedBtn);
document.getElementById("dead-btn").addEventListener("click", killPlayer); document.getElementById("dead-btn").addEventListener("click", killPlayer);
// add the list of dead/alive players
renderDeadAndAliveInformation();
}
function renderDeadAndAliveInformation() {
let infoContainer = document.getElementById("info-container");
let alivePlayers = currentGame.players.filter((player) => !player.dead).sort((a, b) =>
{
return a.card.role > b.card.role ? 1 : -1;
});
let deadPlayers = currentGame.players.filter((player) => player.dead);
deadPlayers.sort((a, b) => { // sort players by the time they died
return new Date(a.deadAt) > new Date(b.deadAt) ? -1 : 1;
});
let killedContainer = document.createElement("div");
killedContainer.setAttribute("id", "killed-container");
let killedHeader = document.createElement("h2");
killedHeader.innerText = "Killed Players";
killedContainer.appendChild(killedHeader);
deadPlayers.forEach((player) => {
const killedPlayer = document.createElement("div");
killedPlayer.setAttribute("class", "killed-player");
killedPlayer.innerText = player.name + ": " + player.card.role;
killedContainer.appendChild(killedPlayer);
});
let aliveContainer = document.createElement("div");
aliveContainer.setAttribute("id", "alive-container");
let aliveHeader = document.createElement("h2");
aliveContainer.appendChild(aliveHeader);
aliveHeader.innerText = "Roles Still Alive";
alivePlayers.forEach((player) => {
const alivePlayer = document.createElement("div");
alivePlayer.setAttribute("class", "alive-player");
alivePlayer.innerText = player.card.role;
aliveContainer.appendChild(alivePlayer);
});
if (infoContainer === null) {
infoContainer = document.createElement("div");
infoContainer.setAttribute("id", "info-container");
infoContainer.appendChild(killedContainer);
infoContainer.appendChild(aliveContainer);
document.getElementById("game-container").appendChild(infoContainer);
} else {
document.getElementById("killed-container").remove();
document.getElementById("alive-container").remove();
document.getElementById("info-container").append(killedContainer);
document.getElementById("info-container").append(aliveContainer);
}
} }
function renderPlayerCard(player) { function renderPlayerCard(player) {
@@ -227,7 +274,7 @@ function renderPlayerCard(player) {
"</div>" + "</div>" +
"<div class='game-card-back'></div>" + "<div class='game-card-back'></div>" +
"</div>"; "</div>";
document.getElementById("game-container").appendChild(playerCard); document.getElementById("card-container").appendChild(playerCard);
document.getElementById("game-card").addEventListener("click", flipCard); document.getElementById("game-card").addEventListener("click", flipCard);
} }
@@ -274,10 +321,15 @@ function renderClock() {
if (delta <= 0) { if (delta <= 0) {
endGameDueToTimeExpired(); endGameDueToTimeExpired();
} else { } else {
let minutes = Math.floor((delta % (1000 * 60 * 60)) / (1000 * 60)); let seconds = Math.floor( (delta / 1000) % 60);
let seconds = Math.floor((delta % (1000 * 60)) / 1000); let minutes = Math.floor( (delta / 1000 / 60) % 60);
let hours = Math.floor( (delta / (1000*60*60)) % 24);
seconds = seconds < 10 ? "0" + seconds : seconds; seconds = seconds < 10 ? "0" + seconds : seconds;
document.getElementById("clock").innerText = minutes + ":" + seconds; minutes = minutes < 10 ? "0" + minutes : minutes;
document.getElementById("clock").innerText = hours > 0
? hours + ":" + minutes + ":" + seconds
: minutes + ":" + seconds;
} }
}, 1000); }, 1000);
} }

View File

@@ -17,13 +17,14 @@ class Card {
} }
class Game { class Game {
constructor(accessCode, size, deck, time) { constructor(accessCode, size, deck, time, hasDreamWolf) {
this.accessCode = accessCode; this.accessCode = accessCode;
this.size = size; this.size = size;
this.deck = deck; this.deck = deck;
this.time = time; this.time = time;
this.players = []; this.players = [];
this.status = "lobby"; this.status = "lobby";
this.hasDreamWolf = hasDreamWolf;
this.endTime = null; this.endTime = null;
} }
} }
@@ -322,11 +323,13 @@ function createGame() {
// send a new game to the server, and then join it // send a new game to the server, and then join it
const playerInfo = {name: document.getElementById("name").value, code: code, id: id}; const playerInfo = {name: document.getElementById("name").value, code: code, id: id};
let gameDeck = buildDeckFromQuantities();
const game = new Game( const game = new Game(
code, code,
gameSize, gameSize,
buildDeckFromQuantities(), gameDeck,
Math.ceil(document.getElementById("time").value) Math.ceil(document.getElementById("time").value),
gameDeck.find((card) => card.role === "Dream Wolf") !== undefined
); );
socket.emit('newGame', game, function() { socket.emit('newGame', game, function() {
socket.emit('joinGame', playerInfo); socket.emit('joinGame', playerInfo);

View File

@@ -9,10 +9,19 @@
margin: 0.3em 0; margin: 0.3em 0;
} }
#game-container #card-container {
min-width: 20em;
}
h3 { h3 {
font-size: 20px; font-size: 20px;
} }
#game-container {
flex-direction: column;
}
#app-content { #app-content {
width: 92%; width: 92%;
} }
@@ -122,6 +131,9 @@
.card-header > p { .card-header > p {
right: 17px; right: 17px;
top: 30px; top: 30px;
#game-container #card-container {
min-width: 25em;
} }
.app-header-secondary { .app-header-secondary {
@@ -973,7 +985,7 @@ label {
border-radius: 3px; border-radius: 3px;
height: 23em; height: 23em;
margin: 0 auto 2em auto; margin: 0 auto 2em auto;
width: 72%; width: 100%;
box-shadow: 0 13px 17px rgba(0,0,0,0.6); box-shadow: 0 13px 17px rgba(0,0,0,0.6);
perspective: 1000px; perspective: 1000px;
transform-style: preserve-3d; transform-style: preserve-3d;
@@ -1100,7 +1112,7 @@ label {
#clock { #clock {
font-size: 1.5em; font-size: 1.5em;
width: 3.8em; width: 3.8em;
margin-bottom: 0.5em; margin: 0 0.5em 0.5em 0;
} }
#flip-instruction { #flip-instruction {
@@ -1115,6 +1127,20 @@ label {
justify-content: center; justify-content: center;
} }
#game-container {
display: flex;
justify-content: center;
align-items: center;
}
#game-container .killed-player, #game-container .alive-player {
background-color: #494f52;
border-radius: 5px;
padding: 5px;
filter: drop-shadow(3px 10px 10px rgba(0,0,0,0.6));
margin: 0.3em;
}
#play-pause { #play-pause {
width: 2.5em; width: 2.5em;
height: 2.5em; height: 2.5em;

View File

@@ -11,5 +11,13 @@ export const utility =
getRandomInt(max) { getRandomInt(max) {
return Math.floor(Math.random() * Math.floor(max)); return Math.floor(Math.random() * Math.floor(max));
} },
shuffle(array) {
for (let i = array.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[array[i], array[j]] = [array[j], array[i]];
}
return array;
}
}; };

View File

@@ -16,7 +16,9 @@
</div> </div>
<div id="message-box"></div> <div id="message-box"></div>
<div id="lobby-container"></div> <div id="lobby-container"></div>
<div id="game-container"></div> <div id="game-container">
<div id="card-container"></div>
</div>
<div id="end-container"></div> <div id="end-container"></div>
<div id="launch"></div> <div id="launch"></div>
</div> </div>