From c51864659ad5cfe57989b6ab820eeb8cf0f3d26d Mon Sep 17 00:00:00 2001 From: AlecM33 Date: Mon, 3 Jan 2022 15:51:48 -0500 Subject: [PATCH] styling tweaks --- client/src/config/defaultCards.js | 29 +++-- ...Double-BlindMinion.png => BlindMinion.png} | Bin .../roles/{KnowingMinion.png => Minion.png} | Bin client/src/images/roles/Sorcerer.png | Bin 1903 -> 0 bytes .../roles/{Shadow.png => Sorceress.png} | Bin .../roles/{Villager.png => Villager1.png} | Bin .../roles/{Villager-2.png => Villager2.png} | Bin client/src/modules/DeckStateManager.js | 3 +- client/src/modules/GameCreationStepManager.js | 116 ++++++++---------- client/src/modules/GameStateRenderer.js | 17 ++- client/src/modules/Templates.js | 40 +++++- client/src/scripts/create.js | 5 +- client/src/styles/GLOBAL.css | 8 ++ client/src/styles/create.css | 104 ++++++++++++++-- client/src/styles/game.css | 22 ++-- client/src/styles/modal.css | 4 +- client/src/views/create.html | 33 ++--- server/modules/ActiveGameRunner.js | 1 - server/modules/GameManager.js | 4 +- 19 files changed, 245 insertions(+), 141 deletions(-) rename client/src/images/roles/{Double-BlindMinion.png => BlindMinion.png} (100%) rename client/src/images/roles/{KnowingMinion.png => Minion.png} (100%) delete mode 100644 client/src/images/roles/Sorcerer.png rename client/src/images/roles/{Shadow.png => Sorceress.png} (100%) rename client/src/images/roles/{Villager.png => Villager1.png} (100%) rename client/src/images/roles/{Villager-2.png => Villager2.png} (100%) diff --git a/client/src/config/defaultCards.js b/client/src/config/defaultCards.js index 9e25dce..115b804 100644 --- a/client/src/config/defaultCards.js +++ b/client/src/config/defaultCards.js @@ -12,31 +12,36 @@ export const defaultCards = [ { role: "Dream Wolf", team: "evil", - description: "If a Werewolf dies, you become a Werewolf. You do not wake up with the Werewolves until this happens. You count for parity only after converting to a wolf.", + description: "You are a Werewolf, but you don't wake up with the other Werewolves until one of them dies.", }, { - role: "Knowing Minion", + role: "Sorceress", team: "evil", - description: "You are an evil villager - you know who the wolves are, and you want them to win.", + description: "Each night, learn if a chosen person is the Seer.", }, { - role: "Double-Blind Minion", + role: "Minion", team: "evil", - description: "You are an evil villager. You don't know who the wolves are, but you want them to win.", + description: "You are an evil Villager, and you know who the Werewolves are.", + }, + { + role: "Blind Minion", + team: "evil", + description: "You are an evil villager, but you don't know who the Werewolves are.", }, { role: "Seer", team: "good", - description: "During each night, choose one person. The moderator will tell you whether that player is a wolf.", + description: "Each night, learn if a chosen person is a Werewolf.", + }, + { + role: "Parity Hunter", + team: "good", + description: "You beat a werewolf in a 1v1 situation, winning the game for the village.", }, { role: "Hunter", team: "good", - description: "If you are alive with a wolf at the end of the game, you best the wolf, and the village wins.", - }, - { - role: "Mason", - team: "good", - description: "Masons know who the other masons are.", + description: "When you are eliminated, choose another player to go with you.", } ]; diff --git a/client/src/images/roles/Double-BlindMinion.png b/client/src/images/roles/BlindMinion.png similarity index 100% rename from client/src/images/roles/Double-BlindMinion.png rename to client/src/images/roles/BlindMinion.png diff --git a/client/src/images/roles/KnowingMinion.png b/client/src/images/roles/Minion.png similarity index 100% rename from client/src/images/roles/KnowingMinion.png rename to client/src/images/roles/Minion.png diff --git a/client/src/images/roles/Sorcerer.png b/client/src/images/roles/Sorcerer.png deleted file mode 100644 index a85b4da539bfca29fb5e7002acf530cba00aa08b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1903 zcmZ`(dr(tn7QbnzJme9BBwAP!SZLG%5?&&Yt003OMbvxiO%UYxX!4A8;xRf{m=#p$kPkxBqsl22E zDF9IVF#uFn0l+F|s?-9&XAA&%a{>UOZU6xJ^sU}cVlYQ;+Ww40?8KH`F)4C8$MKHe zURQuL8h*;lewSN};ePJ3dSLKsOw32FbYi^S2SC6s`khk7-0h=3N;$0pKVPap4){Pl zKKgx2BgtbM6IV^zx~2) z%HEgYqxicE3A@-AC#NLZYaCs-(ufyscyj>Y!{3q<;xay;Seib3eKLbkIpj>(>%gw` zvvW{cEMI94_O$V*hYS7bf$U!%k88$nB8!)T)S9mkbz*4mUDO}gyq|dT@3KKji=WUJ zb{EMSUCr-K6re=3{xa@+s?By)n1YO55YRsb79Qw+d3Y3}5y3AJ$Nr`g0tJnVYXx=ufTJ*7!C6n35~z+cOErI* zk077PLM~eY{Djwf+}rXsPsL!&&hLKqiH@cFrIbtnRe{myjop2JG0MSZ|%W0V& zR{lw-U*DX-LvDa3syCvV!eK#V<>&6E5xfoS?yvp7F*W2C?@C+5zYNA&?yZ$exyp4` zdR@*B6G(7nBqWw`%Hii*3z>EB6WB40u$JzLrSf#D~gZB^mS)>Nn>~?z~D^d|lUpKw`Ol%Vn+`wakGzr;^Lt6~jOAcbG%5yhZ&K z&!>H+ux*ddzqT0P&YBwk5L*%r%f3b+S*ZCRvYXI4MQ`u4r4!GL^t!SrBN8< z&Oa_>&ff1HAiU9ZT(vAVvSz+v1^Ad#Yv|^48q4m7IVfV>!xtbmmXm~movQAsk1@uS zi^w3%3w}WROV^$j=syir?O6}Eupqg7M|XvnSK-FDXfD)y@WAmC^}T)GnOYM#0x#lf ztp62P$bI$)zUZ0dsY;fNd=2?seF$a*tJ7NL4wZk^+ZJvvQ%)CTrlJ=XP%1I4SQ?|cPslW zUtOCe$(ekM)2_1e>)J8uvgtpgc`G4JG3woh%wJct+hUfBnprawv*~k6G8fgAKwz^2 zd@eyDJJP`$(_CF{)hIoE`=rv9MX|0H0zI*uhtM8vIy@P{=_j2r;Zu1J6tXgJPERog zP!3bP`eM3Pc_Vz&+)PPW#g-Xsfml)^BI&pv2vn8o8KU*l-=|_USfcVeKA%y!1f0 zzmz|*0d|&9!3UU>)Ozug-9nTx64)$piM5K@qJ<|7+@NnEqmX(|r@S9!9@c2erbA0t zZ7ehuts`vXO@ya<5Mge9YHb%J3pc;K&|2+DVJw@J@#%1xwzLefCMCXamQdya6UAKi48SjyQrV;!=5L`1pTqx^zC3c+-VRr^4`jG_L=a12nBxX4o3iqiC6krI} z`aHB1cO~%1a;$Yo5y8XGjjW+TGuU7oV0Zu9Fsl=-4 option.role === role); - let existingCard = this.deck.find((card) => card.role === role); - if (option && !existingCard) { + if (option) { option.quantity = 0; this.deck.push(option); this.customRoleOptions.splice(this.customRoleOptions.indexOf(option), 1); diff --git a/client/src/modules/GameCreationStepManager.js b/client/src/modules/GameCreationStepManager.js index a208c07..1a9f681 100644 --- a/client/src/modules/GameCreationStepManager.js +++ b/client/src/modules/GameCreationStepManager.js @@ -4,6 +4,7 @@ import { customCards } from "../config/customCards.js"; import { ModalManager } from "./ModalManager.js"; import {XHRUtility} from "./XHRUtility.js"; import {globals} from "../config/globals.js"; +import {templates} from "./Templates.js"; export class GameCreationStepManager { constructor(deckManager) { @@ -33,14 +34,14 @@ export class GameCreationStepManager { 2: { title: "Create your deck of cards:", forwardHandler: () => { - if (this.deckManager.getDeckSize() >= 5) { + if (this.deckManager.getDeckSize() >= 5 && this.deckManager.getDeckSize() <= 50) { this.currentGame.deck = deckManager.getCurrentDeck().filter((card) => card.quantity > 0) cancelCurrentToast(); this.removeStepElementsFromDOM(this.step); this.incrementStep(); this.renderStep("creation-step-container", this.step); } else { - toast("You must include enough cards for 5 players.", "error", true); + toast("You must have a deck for between 5 and 50 players", "error", true); } }, backHandler: this.defaultBackHandler @@ -191,26 +192,28 @@ function renderRoleSelectionStep(game, containerId, step, deckManager) { const stepContainer = document.createElement("div"); setAttributes(stepContainer, {'id': 'step-' + step, 'class': 'flex-row-container-left-align step'}); - let div = document.createElement("div"); - div.setAttribute("id", "deck-container"); - let deckContainer = document.createElement("div"); - deckContainer.setAttribute("id", "deck"); - - deckContainer = loadIncludedCards(deckManager, deckContainer); - - let deckLabel = document.createElement("label"); - deckLabel.setAttribute("for", "deck"); - deckLabel.innerText = 'Game Deck: ' + deckManager.getDeckSize() + ' Players'; - div.prepend(deckLabel); - div.appendChild(deckContainer); - stepContainer.appendChild(div); - - let customForm = loadCustomRoles(deckManager); - - stepContainer.prepend(customForm); + stepContainer.innerHTML =templates.CREATE_GAME_CUSTOM_ROLES; + stepContainer.innerHTML += templates.CREATE_GAME_DECK; document.getElementById(containerId).appendChild(stepContainer); + let clickHandler = () => { + console.log("fired"); + let actions = document.getElementById("custom-role-actions"); + if (actions.style.display !== 'none') { + actions.style.display = 'none'; + } else { + actions.style.display = 'block'; + } + }; + + //document.getElementById("custom-role-hamburger").addEventListener("click", clickHandler); + + loadIncludedCards(deckManager); + + loadCustomRoles(deckManager); + + initializeRemainingEventListeners(deckManager); } @@ -349,61 +352,41 @@ function showButtons(back, forward, forwardHandler, backHandler, builtGame=null) } // Display a widget for each default card that allows copies of it to be added/removed. Set initial deck state. -function loadIncludedCards(deckManager, deckContainer) { - +function loadIncludedCards(deckManager) { for (let i = 0; i < deckManager.getCurrentDeck().length; i ++) { // each dropdown should include every let card = deckManager.getCurrentDeck()[i]; let cardEl = constructCompactDeckBuilderElement(card, deckManager); - deckContainer.appendChild(cardEl); + if (card.team === globals.ALIGNMENT.GOOD) { + document.getElementById("deck-good").appendChild(cardEl); + } else { + document.getElementById("deck-evil").appendChild(cardEl); + } } - - return deckContainer; } /* Display a dropdown containing all the custom roles. Adding one will add it to the game deck and create a widget for it */ function loadCustomRoles(deckManager) { - let customContainer = document.createElement("div"); - customContainer.setAttribute("id", "custom-roles-container"); - - let formLabel = document.createElement("label"); - formLabel.innerText = 'Custom Roles'; - formLabel.setAttribute("for", "add-card-to-deck-form"); - - let createRoleButton = document.createElement("button"); - createRoleButton.setAttribute("id", "custom-role-btn"); - createRoleButton.classList.add('app-button'); - createRoleButton.innerText = '+ Create Custom Role'; - - let form = document.createElement("form"); - form.setAttribute("id", "add-card-to-deck-form"); - - let selectEl = document.createElement("select"); - selectEl.setAttribute("id", "deck-select"); - addOptionsToList(deckManager.getCurrentCustomRoleOptions(), selectEl); - - form.appendChild(selectEl); - - let submitBtn = document.createElement("input"); - submitBtn.setAttribute("type", "submit"); - submitBtn.setAttribute("value", "Include Role"); - submitBtn.addEventListener('click', (e) => { + let select = document.getElementById("deck-select"); + addOptionsToList(deckManager.getCurrentCustomRoleOptions(), document.getElementById("deck-select")); + document.getElementById("include-role").addEventListener('click', (e) => { e.preventDefault(); - if (selectEl.value && selectEl.value.length > 0) { - deckManager.addToDeck(selectEl.value); - let cardEl = constructCompactDeckBuilderElement(deckManager.getCard(selectEl.value), deckManager); - toast('"' + selectEl.value + '" included.', 'success', true, true, 3); - updateCustomRoleOptionsList(deckManager, selectEl); - document.getElementById("deck").appendChild(cardEl); + if (select.value && select.value.length > 0) { + if (!deckManager.getCard(select.value)) { + deckManager.addToDeck(select.value); + let cardEl = constructCompactDeckBuilderElement(deckManager.getCard(select.value), deckManager); + toast('"' + select.value + '" included.', 'success', true, true, 3); + if (deckManager.getCard(select.value).team === globals.ALIGNMENT.GOOD) { + document.getElementById("deck-good").appendChild(cardEl); + } else { + document.getElementById("deck-evil").appendChild(cardEl); + } + updateCustomRoleOptionsList(deckManager, select); + } else { + toast('"' + select.value + '" already included.', 'error', true, true, 3); + } } }) - form.appendChild(submitBtn); - - customContainer.appendChild(formLabel); - customContainer.appendChild(form); - customContainer.appendChild(createRoleButton); - - return customContainer; } function constructCompactDeckBuilderElement(card, deckManager) { @@ -437,7 +420,6 @@ function constructCompactDeckBuilderElement(card, deckManager) { cardContainer.querySelector('.compact-card-right').addEventListener('click', () => { deckManager.addCopyOfCard(card.role); cardContainer.querySelector('.card-quantity').innerText = deckManager.getCard(card.role).quantity; - document.querySelector('label[for="deck"]').innerText = 'Game Deck: ' + deckManager.getDeckSize() + ' Players'; if (deckManager.getCard(card.role).quantity > 0) { document.getElementById('card-' + card.role.replaceAll(' ', '-')).classList.add('selected-card') } @@ -445,7 +427,6 @@ function constructCompactDeckBuilderElement(card, deckManager) { cardContainer.querySelector('.compact-card-left').addEventListener('click', () => { deckManager.removeCopyOfCard(card.role); cardContainer.querySelector('.card-quantity').innerText = deckManager.getCard(card.role).quantity; - document.querySelector('label[for="deck"]').innerText = 'Game Deck: ' + deckManager.getDeckSize() + ' Players'; if (deckManager.getCard(card.role).quantity === 0) { document.getElementById('card-' + card.role.replaceAll(' ', '-')).classList.remove('selected-card') } @@ -459,7 +440,7 @@ function initializeRemainingEventListeners(deckManager) { let name = document.getElementById("role-name").value.trim(); let description = document.getElementById("role-description").value.trim(); let team = document.getElementById("role-alignment").value.toLowerCase().trim(); - if (!deckManager.getCustomRoleOption(name)) { // confirm there is no existing custom role with the same name + if (!deckManager.getCustomRoleOption(name) && !deckManager.getCard(name)) { // confirm there is no existing custom role with the same name if (name.length > 40) { toast('Your name is too long (max 40 characters).', "error", true); return; @@ -473,7 +454,7 @@ function initializeRemainingEventListeners(deckManager) { ModalManager.dispelModal("add-role-modal", "add-role-modal-background"); toast("Role Created", "success", true); } else { - toast("There is already a custom role with this name.", "error", true); + toast("There is already a role with this name", "error", true, true, 3); } } document.getElementById("custom-role-btn").addEventListener( @@ -494,6 +475,9 @@ function updateCustomRoleOptionsList(deckManager, selectEl) { function addOptionsToList(options, selectEl) { options.sort((a, b) => { + if (a.team !== b.team) { + return a.team === globals.ALIGNMENT.GOOD ? 1 : -1; + } return a.role.localeCompare(b.role); }); for (let i = 0; i < options.length; i ++) { diff --git a/client/src/modules/GameStateRenderer.js b/client/src/modules/GameStateRenderer.js index 27709b9..15c18b4 100644 --- a/client/src/modules/GameStateRenderer.js +++ b/client/src/modules/GameStateRenderer.js @@ -389,8 +389,10 @@ function renderPlayerRole(gameState) { let name = document.querySelector('#role-name'); name.innerText = gameState.client.gameRole; if (gameState.client.alignment === globals.ALIGNMENT.GOOD) { + document.getElementById("game-role").classList.add('game-role-good'); name.classList.add('good'); } else { + document.getElementById("game-role").classList.add('game-role-evil'); name.classList.add('evil'); } name.setAttribute("title", gameState.client.gameRole); @@ -401,10 +403,17 @@ function renderPlayerRole(gameState) { '../images/tombstone.png' ); } else { - document.getElementById("role-image").setAttribute( - 'src', - '../images/roles/' + gameState.client.gameRole.replaceAll(' ', '') + '.png' - ); + if (gameState.client.gameRole.toLowerCase() === 'villager') { + document.getElementById("role-image").setAttribute( + 'src', + '../images/roles/Villager' + Math.ceil(Math.random() * 2) + '.png' + ); + } else { + document.getElementById("role-image").setAttribute( + 'src', + '../images/roles/' + gameState.client.gameRole.replaceAll(' ', '') + '.png' + ); + } } document.querySelector('#role-description').innerText = gameState.client.gameRoleDescription; diff --git a/client/src/modules/Templates.js b/client/src/modules/Templates.js index 3bbade3..2874ac4 100644 --- a/client/src/modules/Templates.js +++ b/client/src/modules/Templates.js @@ -78,7 +78,7 @@ export const templates = { "