mirror of
https://github.com/AlecM33/Werewolf.git
synced 2025-12-26 15:57:50 +01:00
@@ -37,8 +37,8 @@ export const defaultRoles = [
|
||||
{
|
||||
role: 'Doctor',
|
||||
team: 'good',
|
||||
description: `Each night, choose a player to protect from the Werewolves. This can be yourself. If the Werewolves
|
||||
target this person, they still survive to the following day.`
|
||||
description: 'Each night, choose a player to protect from the Werewolves. This can be yourself. If the Werewolves ' +
|
||||
'target this person, they still survive to the following day.'
|
||||
},
|
||||
{
|
||||
role: 'Parity Hunter',
|
||||
|
||||
@@ -8,6 +8,8 @@ export const PRIMITIVES = {
|
||||
MAX_CUSTOM_ROLE_DESCRIPTION_LENGTH: 1000,
|
||||
TOAST_DURATION_DEFAULT: 6,
|
||||
ACCESS_CODE_LENGTH: 4,
|
||||
MAX_MINUTES: 59,
|
||||
MAX_HOURS: 5,
|
||||
PLAYER_ID_COOKIE_KEY: 'play-werewolf-anon-id'
|
||||
};
|
||||
|
||||
@@ -75,6 +77,7 @@ export const EVENT_IDS = {
|
||||
ASSIGN_DEDICATED_MOD: 'assignDedicatedMod',
|
||||
KICK_PERSON: 'kickPerson',
|
||||
UPDATE_GAME_ROLES: 'updateGameRoles',
|
||||
UPDATE_GAME_TIMER: 'updateGameTimer',
|
||||
LEAVE_ROOM: 'leaveRoom'
|
||||
};
|
||||
|
||||
@@ -93,6 +96,7 @@ export const LOBBY_EVENTS = function () {
|
||||
EVENT_IDS.ADD_SPECTATOR,
|
||||
EVENT_IDS.KICK_PERSON,
|
||||
EVENT_IDS.UPDATE_GAME_ROLES,
|
||||
EVENT_IDS.UPDATE_GAME_TIMER,
|
||||
EVENT_IDS.LEAVE_ROOM
|
||||
];
|
||||
};
|
||||
|
||||
@@ -11,7 +11,7 @@ export const HTMLFragments = {
|
||||
<div id='game-parameters'>
|
||||
<div>
|
||||
<img alt='clock' src='/images/clock.svg'/>
|
||||
<div id='game-time'></div>
|
||||
<div id='timer-parameters'></div>
|
||||
</div>
|
||||
<div>
|
||||
<img alt='person' src='/images/person.svg'/>
|
||||
@@ -46,6 +46,7 @@ export const HTMLFragments = {
|
||||
</div>`,
|
||||
START_GAME_PROMPT:
|
||||
`<button id='edit-roles-button'>Edit Roles</button>
|
||||
<button id='edit-timer-button'>Edit Timer</button>
|
||||
<button id='start-game-button'>Start Game</button>`,
|
||||
LEAVE_GAME_PROMPT:
|
||||
'<button id=\'leave-game-button\'>Leave Room</button>',
|
||||
@@ -58,6 +59,11 @@ export const HTMLFragments = {
|
||||
<button class="app-button" id="save-role-changes-button">
|
||||
<p>Save</p><img src="../images/save-svgrepo-com.svg" alt='save'>
|
||||
</button>`,
|
||||
TIMER_EDIT_BUTTONS:
|
||||
`<button class="app-button cancel" id="cancel-timer-changes-button">Cancel</button>
|
||||
<button class="app-button" id="save-timer-changes-button">
|
||||
<p>Save</p><img src="../images/save-svgrepo-com.svg" alt='save'>
|
||||
</button>`,
|
||||
PLAYER_GAME_VIEW:
|
||||
`<div id='game-header'>
|
||||
<div>
|
||||
|
||||
@@ -53,16 +53,10 @@ export class GameCreationStepManager {
|
||||
if (e.type === 'click' || e.code === 'Enter') {
|
||||
let hours = parseInt(document.getElementById('game-hours').value);
|
||||
let minutes = parseInt(document.getElementById('game-minutes').value);
|
||||
hours = isNaN(hours) ? null : hours;
|
||||
minutes = isNaN(minutes) ? null : minutes;
|
||||
if ((hours === null && minutes === null)
|
||||
|| (hours === null && minutes > 0 && minutes < 60)
|
||||
|| (minutes === null && hours > 0 && hours < 6)
|
||||
|| (hours === 0 && minutes > 0 && minutes < 60)
|
||||
|| (minutes === 0 && hours > 0 && hours < 6)
|
||||
|| (hours > 0 && hours < 6 && minutes >= 0 && minutes < 60)
|
||||
) {
|
||||
if (hasTimer(hours, minutes)) {
|
||||
hours = this.standardizeNumberInput(hours);
|
||||
minutes = this.standardizeNumberInput(minutes);
|
||||
if (this.timerIsValid(hours, minutes)) {
|
||||
if (this.hasTimer(hours, minutes)) {
|
||||
this.currentGame.hasTimer = true;
|
||||
this.currentGame.timerParams = {
|
||||
hours: hours,
|
||||
@@ -77,11 +71,7 @@ export class GameCreationStepManager {
|
||||
this.incrementStep();
|
||||
this.renderStep('creation-step-container', this.step);
|
||||
} else {
|
||||
if (hours === 0 && minutes === 0) {
|
||||
toast('You must enter a non-zero amount of time.', 'error', true);
|
||||
} else {
|
||||
toast('Invalid timer options. Hours can be a max of 5, Minutes a max of 59.', 'error', true);
|
||||
}
|
||||
toast('Invalid timer options. Hours can be a max of 5, Minutes a max of 59.', 'error', true);
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -149,7 +139,7 @@ export class GameCreationStepManager {
|
||||
restoreButton();
|
||||
break;
|
||||
case 400:
|
||||
toast('Your game has invalid parameters..', 'error', true, true);
|
||||
toast('Your game has invalid parameters.', 'error', true, true);
|
||||
restoreButton();
|
||||
break;
|
||||
case 201:
|
||||
@@ -198,7 +188,7 @@ export class GameCreationStepManager {
|
||||
showButtons(true, true, this.steps[step].forwardHandler, this.steps[step].backHandler);
|
||||
break;
|
||||
case 3:
|
||||
renderTimerStep(containerId, step, this.currentGame, this.steps);
|
||||
this.renderTimerStep(containerId, step, this.currentGame, this.steps);
|
||||
showButtons(true, true, this.steps[step].forwardHandler, this.steps[step].backHandler);
|
||||
break;
|
||||
case 4:
|
||||
@@ -297,6 +287,67 @@ export class GameCreationStepManager {
|
||||
|
||||
initializeRemainingEventListeners(this.deckManager, this.roleBox);
|
||||
};
|
||||
|
||||
renderTimerStep (containerId, stepNumber, game, steps) {
|
||||
const div = document.createElement('div');
|
||||
div.setAttribute('id', 'step-' + stepNumber);
|
||||
div.classList.add('step');
|
||||
|
||||
const timeContainer = document.createElement('div');
|
||||
timeContainer.setAttribute('id', 'game-time');
|
||||
|
||||
const hoursDiv = document.createElement('div');
|
||||
const hoursLabel = document.createElement('label');
|
||||
hoursLabel.setAttribute('for', 'game-hours');
|
||||
hoursLabel.innerText = 'Hours';
|
||||
const hours = document.createElement('input');
|
||||
hours.addEventListener('keyup', steps[stepNumber].forwardHandler);
|
||||
setAttributes(hours, { type: 'number', id: 'game-hours', name: 'game-hours', min: '0', max: '5', value: game.timerParams?.hours });
|
||||
|
||||
const minutesDiv = document.createElement('div');
|
||||
const minsLabel = document.createElement('label');
|
||||
minsLabel.setAttribute('for', 'game-minutes');
|
||||
minsLabel.innerText = 'Minutes';
|
||||
const minutes = document.createElement('input');
|
||||
minutes.addEventListener('keyup', steps[stepNumber].forwardHandler);
|
||||
setAttributes(minutes, { type: 'number', id: 'game-minutes', name: 'game-minutes', min: '1', max: '60', value: game.timerParams?.minutes });
|
||||
|
||||
hoursDiv.appendChild(hoursLabel);
|
||||
hoursDiv.appendChild(hours);
|
||||
minutesDiv.appendChild(minsLabel);
|
||||
minutesDiv.appendChild(minutes);
|
||||
timeContainer.appendChild(hoursDiv);
|
||||
timeContainer.appendChild(minutesDiv);
|
||||
div.appendChild(timeContainer);
|
||||
|
||||
document.getElementById(containerId).appendChild(div);
|
||||
}
|
||||
|
||||
timerIsValid (hours, minutes) {
|
||||
let valid = true;
|
||||
|
||||
if (hours === null && minutes === null) {
|
||||
return valid;
|
||||
}
|
||||
|
||||
if (hours !== null) {
|
||||
valid = hours > 0 && hours <= PRIMITIVES.MAX_HOURS;
|
||||
}
|
||||
|
||||
if (minutes !== null) {
|
||||
valid = minutes > 0 && minutes <= PRIMITIVES.MAX_MINUTES;
|
||||
}
|
||||
|
||||
return valid;
|
||||
}
|
||||
|
||||
hasTimer (hours, minutes) {
|
||||
return hours !== null || minutes !== null;
|
||||
}
|
||||
|
||||
standardizeNumberInput (input) {
|
||||
return (isNaN(input) || input === 0) ? null : input;
|
||||
}
|
||||
}
|
||||
|
||||
function renderNameStep (containerId, step, game, steps) {
|
||||
@@ -358,41 +409,6 @@ function renderModerationTypeStep (game, containerId, stepNumber) {
|
||||
document.getElementById(containerId).appendChild(stepContainer);
|
||||
}
|
||||
|
||||
function renderTimerStep (containerId, stepNumber, game, steps) {
|
||||
const div = document.createElement('div');
|
||||
div.setAttribute('id', 'step-' + stepNumber);
|
||||
div.classList.add('step');
|
||||
|
||||
const timeContainer = document.createElement('div');
|
||||
timeContainer.setAttribute('id', 'game-time');
|
||||
|
||||
const hoursDiv = document.createElement('div');
|
||||
const hoursLabel = document.createElement('label');
|
||||
hoursLabel.setAttribute('for', 'game-hours');
|
||||
hoursLabel.innerText = 'Hours';
|
||||
const hours = document.createElement('input');
|
||||
hours.addEventListener('keyup', steps[stepNumber].forwardHandler);
|
||||
setAttributes(hours, { type: 'number', id: 'game-hours', name: 'game-hours', min: '0', max: '5', value: game.timerParams?.hours });
|
||||
|
||||
const minutesDiv = document.createElement('div');
|
||||
const minsLabel = document.createElement('label');
|
||||
minsLabel.setAttribute('for', 'game-minutes');
|
||||
minsLabel.innerText = 'Minutes';
|
||||
const minutes = document.createElement('input');
|
||||
minutes.addEventListener('keyup', steps[stepNumber].forwardHandler);
|
||||
setAttributes(minutes, { type: 'number', id: 'game-minutes', name: 'game-minutes', min: '1', max: '60', value: game.timerParams?.minutes });
|
||||
|
||||
hoursDiv.appendChild(hoursLabel);
|
||||
hoursDiv.appendChild(hours);
|
||||
minutesDiv.appendChild(minsLabel);
|
||||
minutesDiv.appendChild(minutes);
|
||||
timeContainer.appendChild(hoursDiv);
|
||||
timeContainer.appendChild(minutesDiv);
|
||||
div.appendChild(timeContainer);
|
||||
|
||||
document.getElementById(containerId).appendChild(div);
|
||||
}
|
||||
|
||||
function renderReviewAndCreateStep (containerId, stepNumber, game, deckManager) {
|
||||
const div = document.createElement('div');
|
||||
div.setAttribute('id', 'step-' + stepNumber);
|
||||
@@ -591,10 +607,6 @@ function processNewCustomRoleSubmission (name, description, team, deckManager, i
|
||||
}
|
||||
}
|
||||
|
||||
function hasTimer (hours, minutes) {
|
||||
return hours !== null || minutes !== null;
|
||||
}
|
||||
|
||||
function validateName (name) {
|
||||
return typeof name === 'string' && name.length > 0 && name.length <= PRIMITIVES.MAX_PERSON_NAME_LENGTH;
|
||||
}
|
||||
|
||||
@@ -166,6 +166,7 @@ export class RoleBox {
|
||||
};
|
||||
|
||||
displayDefaultRoles = (selectEl) => {
|
||||
document.querySelector('#custom-role-placeholder')?.remove();
|
||||
document.querySelectorAll('#role-select .default-role, #role-select .custom-role').forEach(e => e.remove());
|
||||
this.categoryTransition.play();
|
||||
for (let i = 0; i < this.defaultRoles.length; i ++) {
|
||||
@@ -184,9 +185,21 @@ export class RoleBox {
|
||||
this.addRoleEventListeners(selectEl, true, true, false, false, false);
|
||||
};
|
||||
|
||||
displayCustomRolePlaceHolder = () => {
|
||||
const placeholder = document.createElement('div');
|
||||
placeholder.setAttribute('id', 'custom-role-placeholder');
|
||||
placeholder.innerText = 'Create a role with the button below.';
|
||||
document.getElementById('role-select').appendChild(placeholder);
|
||||
};
|
||||
|
||||
displayCustomRoles = (selectEl) => {
|
||||
document.querySelector('#custom-role-placeholder')?.remove();
|
||||
document.querySelectorAll('#role-select .default-role, #role-select .custom-role').forEach(e => e.remove());
|
||||
this.categoryTransition.play();
|
||||
if (this.customRoles.length === 0) {
|
||||
this.displayCustomRolePlaceHolder();
|
||||
return;
|
||||
}
|
||||
this.customRoles.sort((a, b) => {
|
||||
if (a.team !== b.team) {
|
||||
return a.team === ALIGNMENT.GOOD ? -1 : 1;
|
||||
|
||||
@@ -60,6 +60,70 @@ export class Lobby {
|
||||
});
|
||||
};
|
||||
|
||||
this.editTimerHandler = (e) => {
|
||||
e.preventDefault();
|
||||
document.querySelector('#mid-game-timer-editor')?.remove();
|
||||
const timerEditContainer = document.createElement('div');
|
||||
const timerEditContainerBackground = document.createElement('div');
|
||||
timerEditContainerBackground.setAttribute('id', 'timer-edit-container-background');
|
||||
timerEditContainer.setAttribute('id', 'mid-game-timer-editor');
|
||||
document.getElementById('game-content').style.display = 'none';
|
||||
document.body.appendChild(timerEditContainer);
|
||||
document.body.appendChild(timerEditContainerBackground);
|
||||
const timerEditPrompt = document.createElement('div');
|
||||
timerEditPrompt.setAttribute('id', 'timer-edit-prompt');
|
||||
timerEditPrompt.innerHTML = HTMLFragments.TIMER_EDIT_BUTTONS;
|
||||
this.gameCreationStepManager.steps['3'].forwardHandler = (e) => {
|
||||
e.preventDefault();
|
||||
if (e.type === 'click' || e.code === 'Enter') {
|
||||
timerEditPrompt.querySelector('#save-timer-changes-button')?.click();
|
||||
}
|
||||
};
|
||||
this.gameCreationStepManager
|
||||
.renderTimerStep('mid-game-timer-editor', '3', this.stateBucket.currentGameState, this.gameCreationStepManager.steps);
|
||||
timerEditPrompt.querySelector('#save-timer-changes-button').addEventListener('click', () => {
|
||||
let hours = parseInt(document.getElementById('game-hours').value);
|
||||
let minutes = parseInt(document.getElementById('game-minutes').value);
|
||||
hours = this.gameCreationStepManager.standardizeNumberInput(hours);
|
||||
minutes = this.gameCreationStepManager.standardizeNumberInput(minutes);
|
||||
if (this.gameCreationStepManager.timerIsValid(hours, minutes)) {
|
||||
let hasTimer, timerParams;
|
||||
if (this.gameCreationStepManager.hasTimer(hours, minutes)) {
|
||||
hasTimer = true;
|
||||
timerParams = {
|
||||
hours: hours,
|
||||
minutes: minutes
|
||||
};
|
||||
} else {
|
||||
hasTimer = false;
|
||||
timerParams = null;
|
||||
}
|
||||
document.querySelector('#mid-game-timer-editor')?.remove();
|
||||
document.querySelector('#timer-edit-container-background')?.remove();
|
||||
document.getElementById('game-content').style.display = 'flex';
|
||||
this.socket.emit(
|
||||
SOCKET_EVENTS.IN_GAME_MESSAGE,
|
||||
EVENT_IDS.UPDATE_GAME_TIMER,
|
||||
stateBucket.currentGameState.accessCode,
|
||||
{ hasTimer: hasTimer, timerParams: timerParams },
|
||||
() => {
|
||||
toast('Timer updated successfully!', 'success');
|
||||
}
|
||||
);
|
||||
} else {
|
||||
toast('Invalid timer options. Hours can be a max of 5, Minutes a max of 59.', 'error', true);
|
||||
}
|
||||
});
|
||||
|
||||
timerEditPrompt.querySelector('#cancel-timer-changes-button').addEventListener('click', () => {
|
||||
document.querySelector('#mid-game-timer-editor')?.remove();
|
||||
document.querySelector('#timer-edit-container-background')?.remove();
|
||||
document.getElementById('game-content').style.display = 'flex';
|
||||
});
|
||||
|
||||
timerEditContainer.appendChild(timerEditPrompt);
|
||||
};
|
||||
|
||||
this.editRolesHandler = (e) => {
|
||||
e.preventDefault();
|
||||
document.querySelector('#mid-game-role-editor')?.remove();
|
||||
@@ -136,11 +200,17 @@ export class Lobby {
|
||||
'Participants (' + inLobbyCount + '/' + this.stateBucket.currentGameState.gameSize + ' Players)';
|
||||
}
|
||||
|
||||
populateHeader () {
|
||||
setTimer () {
|
||||
const timeString = getTimeString(this.stateBucket.currentGameState);
|
||||
const time = this.container.querySelector('#game-time');
|
||||
const time = this.container.querySelector('#timer-parameters');
|
||||
time.innerText = timeString;
|
||||
|
||||
return timeString;
|
||||
}
|
||||
|
||||
populateHeader () {
|
||||
const timeString = this.setTimer();
|
||||
|
||||
const link = this.setLink(timeString);
|
||||
|
||||
this.setPlayerCount();
|
||||
@@ -235,6 +305,13 @@ export class Lobby {
|
||||
this.setPlayerCount();
|
||||
});
|
||||
|
||||
this.socket.on(EVENT_IDS.UPDATE_GAME_TIMER, (hasTimer, timerParams) => {
|
||||
this.stateBucket.currentGameState.hasTimer = hasTimer;
|
||||
this.stateBucket.currentGameState.timerParams = timerParams;
|
||||
const timeString = this.setTimer();
|
||||
this.setLink(timeString);
|
||||
});
|
||||
|
||||
this.socket.on(EVENT_IDS.LEAVE_ROOM, (leftId, gameIsStartable) => {
|
||||
if (leftId === this.stateBucket.currentGameState.client.id) {
|
||||
window.location = '/?message=' + encodeURIComponent('You left the room.');
|
||||
@@ -277,6 +354,7 @@ export class Lobby {
|
||||
if (existingPrompt) {
|
||||
enableStartButton(existingPrompt, this.startGameHandler);
|
||||
document.getElementById('edit-roles-button').addEventListener('click', this.editRolesHandler);
|
||||
document.getElementById('edit-timer-button').addEventListener('click', this.editTimerHandler);
|
||||
} else {
|
||||
const newPrompt = document.createElement('div');
|
||||
newPrompt.setAttribute('id', 'start-game-prompt');
|
||||
@@ -285,6 +363,7 @@ export class Lobby {
|
||||
document.body.appendChild(newPrompt);
|
||||
enableStartButton(newPrompt, this.startGameHandler);
|
||||
document.getElementById('edit-roles-button').addEventListener('click', this.editRolesHandler);
|
||||
document.getElementById('edit-timer-button').addEventListener('click', this.editTimerHandler);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -337,14 +416,10 @@ function getTimeString (gameState) {
|
||||
const hours = gameState.timerParams.hours;
|
||||
const minutes = gameState.timerParams.minutes;
|
||||
if (hours) {
|
||||
timeString += hours > 1
|
||||
? hours + ' hours '
|
||||
: hours + ' hour ';
|
||||
timeString += hours + 'h ';
|
||||
}
|
||||
if (minutes) {
|
||||
timeString += minutes > 1
|
||||
? minutes + ' minutes '
|
||||
: minutes + ' minute ';
|
||||
timeString += minutes + 'm';
|
||||
}
|
||||
return timeString;
|
||||
} else {
|
||||
|
||||
@@ -78,6 +78,7 @@ function syncWithGame (socket, cookie, window) {
|
||||
{ personId: cookie },
|
||||
(err, gameState) => {
|
||||
if (err) {
|
||||
console.log(err);
|
||||
retrySync(accessCode, socket, cookie);
|
||||
} else {
|
||||
handleGameState(gameState, cookie, socket);
|
||||
@@ -220,7 +221,10 @@ function setClientSocketHandlers (stateBucket, socket) {
|
||||
|
||||
socket.on(EVENT_IDS.START_GAME, () => { fetchGameStateHandler(startGameStateAckFn); });
|
||||
|
||||
socket.on(EVENT_IDS.RESTART_GAME, () => { fetchGameStateHandler(restartGameStateAckFn); });
|
||||
socket.on(EVENT_IDS.RESTART_GAME, () => {
|
||||
document.querySelector('#game-control-prompt')?.remove();
|
||||
fetchGameStateHandler(restartGameStateAckFn);
|
||||
});
|
||||
|
||||
socket.on(EVENT_IDS.SYNC_GAME_STATE, () => {
|
||||
socket.emit(
|
||||
|
||||
@@ -87,8 +87,8 @@ textarea {
|
||||
}
|
||||
|
||||
.toast-error {
|
||||
background-color: #fdaeb7;
|
||||
border: 3px solid #c78a8a;
|
||||
background-color: #f98e9a;
|
||||
border: 3px solid #c57272;
|
||||
}
|
||||
|
||||
.toast-neutral {
|
||||
@@ -338,12 +338,13 @@ input {
|
||||
border-radius: 5px;
|
||||
font-family: 'signika-negative', sans-serif;
|
||||
font-weight: 100;
|
||||
box-shadow: 0 1px 1px rgba(0,0,0,0.11),
|
||||
0 2px 2px rgba(0,0,0,0.11),
|
||||
0 4px 4px rgba(0,0,0,0.11),
|
||||
0 8px 8px rgba(0,0,0,0.11),
|
||||
0 16px 16px rgba(0,0,0,0.11),
|
||||
0 32px 32px rgba(0,0,0,0.11);
|
||||
box-shadow:
|
||||
0 1px 1px rgba(0,0,0,0.11),
|
||||
0 2px 2px rgba(0,0,0,0.11),
|
||||
0 4px 4px rgba(0,0,0,0.11),
|
||||
0 8px 8px rgba(0,0,0,0.11),
|
||||
0 16px 16px rgba(0,0,0,0.11),
|
||||
0 32px 32px rgba(0,0,0,0.11);
|
||||
left: 0;
|
||||
right: 0;
|
||||
width: fit-content;
|
||||
|
||||
@@ -164,7 +164,7 @@
|
||||
}
|
||||
|
||||
#deck-status-container {
|
||||
width: 20em;
|
||||
width: 25em;
|
||||
max-width: 95%;
|
||||
height: 20em;
|
||||
overflow-y: auto;
|
||||
@@ -191,14 +191,14 @@
|
||||
margin-top: 0.5em;
|
||||
}
|
||||
|
||||
#deck-list-placeholder {
|
||||
#deck-list-placeholder, #custom-role-placeholder {
|
||||
margin: auto;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
width: 290px;
|
||||
width: fit-content;
|
||||
height: 50px;
|
||||
font-size: 20px;
|
||||
text-align: center;
|
||||
@@ -457,7 +457,7 @@ input[type="number"] {
|
||||
#role-select {
|
||||
margin: 0.5em 1em 1.5em 0;
|
||||
overflow-y: auto;
|
||||
height: 16em;
|
||||
height: 20em;
|
||||
}
|
||||
|
||||
.default-role, .custom-role, .added-role {
|
||||
|
||||
@@ -106,13 +106,13 @@
|
||||
max-width: 17em;
|
||||
}
|
||||
|
||||
#save-role-changes-button, #cancel-role-changes-button {
|
||||
#save-role-changes-button, #cancel-role-changes-button, #save-timer-changes-button, #cancel-timer-changes-button {
|
||||
padding: 10px;
|
||||
font-size: 25px;
|
||||
margin: 0.5em 0;
|
||||
}
|
||||
|
||||
#role-edit-prompt {
|
||||
#role-edit-prompt, #timer-edit-prompt {
|
||||
display: flex;
|
||||
margin: 10px 0;
|
||||
padding: 10px 0;
|
||||
@@ -123,11 +123,15 @@
|
||||
background-color: #16141e;
|
||||
}
|
||||
|
||||
#role-edit-prompt button {
|
||||
#timer-edit-prompt {
|
||||
margin-top: 2em;
|
||||
}
|
||||
|
||||
#role-edit-prompt button, #timer-edit-prompt button {
|
||||
margin: 0 20px;
|
||||
}
|
||||
|
||||
#save-role-changes-button img {
|
||||
#save-role-changes-button img, #save-timer-changes-button img {
|
||||
width: 20px;
|
||||
margin-left: 10px;
|
||||
}
|
||||
@@ -136,7 +140,9 @@
|
||||
#end-of-game-buttons #return-to-lobby-button,
|
||||
#mod-transfer-button,
|
||||
#edit-roles-button,
|
||||
#save-role-changes-button {
|
||||
#save-role-changes-button,
|
||||
#edit-timer-button,
|
||||
#save-timer-changes-button {
|
||||
background-color: #045ea6;
|
||||
border: 2px solid #024070;
|
||||
}
|
||||
@@ -145,12 +151,14 @@
|
||||
#end-of-game-buttons #return-to-lobby-button:hover,
|
||||
#mod-transfer-button:hover,
|
||||
#edit-roles-button:hover,
|
||||
#save-role-changes-button:hover {
|
||||
#save-role-changes-button:hover,
|
||||
#edit-timer-button:hover,
|
||||
#save-timer-changes-button:hover {
|
||||
background-color: rgba(0, 120, 215, 0.45);
|
||||
border: 2px solid #045EA6;
|
||||
}
|
||||
|
||||
#mid-game-role-editor {
|
||||
#mid-game-role-editor, #mid-game-timer-editor {
|
||||
display: flex;
|
||||
border-radius: 5px;
|
||||
position: fixed;
|
||||
@@ -164,7 +172,20 @@
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
#role-edit-container-background {
|
||||
#mid-game-timer-editor #game-time {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
border-radius: 5px;
|
||||
margin: 1em;
|
||||
background-color: #16141e;
|
||||
border: 2px solid #3b3a4a;
|
||||
}
|
||||
|
||||
#timer-parameters {
|
||||
width: 65px;
|
||||
}
|
||||
|
||||
#role-edit-container-background, #timer-edit-container-background {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
@@ -175,17 +196,15 @@
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#mid-game-role-editor #step-2 {
|
||||
#mid-game-role-editor #step-2 , #mid-game-timer-editor #step-3 {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
overflow: auto;
|
||||
align-items: center;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
#save-button {
|
||||
|
||||
}
|
||||
|
||||
#mid-game-role-editor #custom-roles-container {
|
||||
height: fit-content;
|
||||
@@ -639,6 +658,7 @@ label[for='moderator'] {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
animation: fade-in-slide-up 0.5s ease-in-out;
|
||||
justify-content: center;
|
||||
position: fixed;
|
||||
z-index: 3;
|
||||
@@ -678,16 +698,21 @@ label[for='moderator'] {
|
||||
box-shadow: 0 -6px 40px black;
|
||||
}
|
||||
|
||||
#start-game-button, #end-game-button, #return-to-lobby-button, #edit-roles-button, #leave-game-button {
|
||||
#start-game-button,
|
||||
#end-game-button,
|
||||
#return-to-lobby-button,
|
||||
#edit-roles-button,
|
||||
#leave-game-button,
|
||||
#edit-timer-button {
|
||||
font-family: 'signika-negative', sans-serif !important;
|
||||
padding: 10px;
|
||||
padding: 7px;
|
||||
border-radius: 5px;
|
||||
color: #e7e7e7;
|
||||
cursor: pointer;
|
||||
border: 2px solid transparent;
|
||||
transition: background-color, border 0.3s ease-out;
|
||||
text-shadow: 0 3px 4px rgb(0 0 0 / 85%);
|
||||
font-size: 25px;
|
||||
font-size: 22px;
|
||||
user-select: none;
|
||||
-ms-user-select: none;
|
||||
-webkit-user-select: none;
|
||||
@@ -997,6 +1022,10 @@ canvas {
|
||||
}
|
||||
|
||||
@media(max-width: 500px) {
|
||||
#game-control-prompt button, #start-game-prompt button, #leave-game-prompt button {
|
||||
margin: 0 10px;
|
||||
}
|
||||
|
||||
#client-container button img {
|
||||
width: 18px;
|
||||
pointer-events: none;
|
||||
@@ -1068,7 +1097,12 @@ canvas {
|
||||
height: 65px;
|
||||
}
|
||||
|
||||
#start-game-button, #end-game-button, #return-to-lobby-button, #edit-roles-button, #leave-game-button {
|
||||
#start-game-button,
|
||||
#end-game-button,
|
||||
#return-to-lobby-button,
|
||||
#edit-roles-button,
|
||||
#leave-game-button,
|
||||
#edit-timer-button {
|
||||
font-size: 20px;
|
||||
padding: 5px;
|
||||
}
|
||||
@@ -1151,11 +1185,7 @@ canvas {
|
||||
@keyframes fade-in-slide-up {
|
||||
0% {
|
||||
opacity: 0;
|
||||
transform: translateY(20px);
|
||||
}
|
||||
5% {
|
||||
opacity: 1;
|
||||
transform: translateY(0px);
|
||||
transform: translateY(10px);
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
|
||||
@@ -78,6 +78,7 @@ const EVENT_IDS = {
|
||||
TIMER_EVENT: 'timerEvent',
|
||||
KICK_PERSON: 'kickPerson',
|
||||
UPDATE_GAME_ROLES: 'updateGameRoles',
|
||||
UPDATE_GAME_TIMER: 'updateGameTimer',
|
||||
LEAVE_ROOM: 'leaveRoom',
|
||||
BROADCAST: 'broadcast'
|
||||
};
|
||||
@@ -103,6 +104,7 @@ const SYNCABLE_EVENTS = function () {
|
||||
EVENT_IDS.END_TIMER,
|
||||
EVENT_IDS.KICK_PERSON,
|
||||
EVENT_IDS.UPDATE_GAME_ROLES,
|
||||
EVENT_IDS.UPDATE_GAME_TIMER,
|
||||
EVENT_IDS.LEAVE_ROOM
|
||||
];
|
||||
};
|
||||
|
||||
@@ -56,6 +56,22 @@ class GameCreationRequest {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static timerParamsAreValid = (hasTimer, timerParams) => {
|
||||
if (hasTimer === false) {
|
||||
return timerParams === null;
|
||||
} else {
|
||||
if (timerParams === null || typeof timerParams !== 'object') {
|
||||
return false;
|
||||
}
|
||||
|
||||
return (timerParams.hours === null && timerParams.minutes > 0 && timerParams.minutes < 60)
|
||||
|| (timerParams.minutes === null && timerParams.hours > 0 && timerParams.hours < 6)
|
||||
|| (timerParams.hours === 0 && timerParams.minutes > 0 && timerParams.minutes < 60)
|
||||
|| (timerParams.minutes === 0 && timerParams.hours > 0 && timerParams.hours < 6)
|
||||
|| (timerParams.hours > 0 && timerParams.hours < 6 && timerParams.minutes >= 0 && timerParams.minutes < 60);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function valid (gameParams) {
|
||||
@@ -65,24 +81,8 @@ function valid (gameParams) {
|
||||
&& typeof gameParams.moderatorName === 'string'
|
||||
&& gameParams.moderatorName.length > 0
|
||||
&& gameParams.moderatorName.length <= 30
|
||||
&& timerParamsAreValid(gameParams.hasTimer, gameParams.timerParams)
|
||||
&& GameCreationRequest.timerParamsAreValid(gameParams.hasTimer, gameParams.timerParams)
|
||||
&& GameCreationRequest.deckIsValid(gameParams.deck);
|
||||
}
|
||||
|
||||
function timerParamsAreValid (hasTimer, timerParams) {
|
||||
if (hasTimer === false) {
|
||||
return timerParams === null;
|
||||
} else {
|
||||
if (timerParams === null || typeof timerParams !== 'object') {
|
||||
return false;
|
||||
}
|
||||
|
||||
return (timerParams.hours === null && timerParams.minutes > 0 && timerParams.minutes < 60)
|
||||
|| (timerParams.minutes === null && timerParams.hours > 0 && timerParams.hours < 6)
|
||||
|| (timerParams.hours === 0 && timerParams.minutes > 0 && timerParams.minutes < 60)
|
||||
|| (timerParams.minutes === 0 && timerParams.hours > 0 && timerParams.hours < 6)
|
||||
|| (timerParams.hours > 0 && timerParams.hours < 6 && timerParams.minutes >= 0 && timerParams.minutes < 60);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = GameCreationRequest;
|
||||
|
||||
@@ -69,7 +69,7 @@ const Events = [
|
||||
}
|
||||
vars.ackFn({ errorFlag: 1, message: 'This name is taken.' });
|
||||
} else if (socketArgs.newName.length > PRIMITIVES.MAX_PERSON_NAME_LENGTH) {
|
||||
vars.ackFn({ errorFlag: 1, message: 'Your new name is too long - the max is' + PRIMITIVES.MAX_PERSON_NAME_LENGTH + ' characters.' });
|
||||
vars.ackFn({ errorFlag: 1, message: 'Your new name is too long - the max is ' + PRIMITIVES.MAX_PERSON_NAME_LENGTH + ' characters.' });
|
||||
vars.hasNameChanged = false;
|
||||
} else if (socketArgs.newName.length === 0) {
|
||||
vars.ackFn({ errorFlag: 1, message: 'Your new name cannot be empty.' });
|
||||
@@ -381,6 +381,25 @@ const Events = [
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
id: EVENT_IDS.UPDATE_GAME_TIMER,
|
||||
stateChange: async (game, socketArgs, vars) => {
|
||||
if (GameCreationRequest.timerParamsAreValid(socketArgs.hasTimer, socketArgs.timerParams)) {
|
||||
game.hasTimer = socketArgs.hasTimer;
|
||||
game.timerParams = socketArgs.timerParams;
|
||||
}
|
||||
},
|
||||
communicate: async (game, socketArgs, vars) => {
|
||||
if (vars.ackFn) {
|
||||
vars.ackFn();
|
||||
}
|
||||
vars.gameManager.namespace.in(game.accessCode).emit(
|
||||
EVENT_IDS.UPDATE_GAME_TIMER,
|
||||
game.hasTimer,
|
||||
game.timerParams
|
||||
);
|
||||
}
|
||||
},
|
||||
{
|
||||
id: EVENT_IDS.END_TIMER,
|
||||
stateChange: async (game, socketArgs, vars) => {
|
||||
|
||||
Reference in New Issue
Block a user