This commit is contained in:
AlecM33
2022-07-16 22:40:49 -04:00
parent 7a66d8d51f
commit 130718d1c5
8 changed files with 100 additions and 99 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 73 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 99 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 122 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 79 KiB

View File

@@ -199,7 +199,7 @@ export class GameStateRenderer {
}); });
const teamGood = this.stateBucket.currentGameState.people.filter((person) => person.alignment === globals.ALIGNMENT.GOOD); const teamGood = this.stateBucket.currentGameState.people.filter((person) => person.alignment === globals.ALIGNMENT.GOOD);
const teamEvil = this.stateBucket.currentGameState.people.filter((person) => person.alignment === globals.ALIGNMENT.EVIL); const teamEvil = this.stateBucket.currentGameState.people.filter((person) => person.alignment === globals.ALIGNMENT.EVIL);
renderGroupOfPlayers( this.renderGroupOfPlayers(
teamEvil, teamEvil,
this.killPlayerHandlers, this.killPlayerHandlers,
this.revealRoleHandlers, this.revealRoleHandlers,
@@ -208,7 +208,7 @@ export class GameStateRenderer {
this.stateBucket.currentGameState.moderator.userType, this.stateBucket.currentGameState.moderator.userType,
this.socket this.socket
); );
renderGroupOfPlayers( this.renderGroupOfPlayers(
teamGood, teamGood,
this.killPlayerHandlers, this.killPlayerHandlers,
this.revealRoleHandlers, this.revealRoleHandlers,
@@ -222,27 +222,33 @@ export class GameStateRenderer {
this.stateBucket.currentGameState.people.length + ' Alive'; this.stateBucket.currentGameState.people.length + ' Alive';
} }
removePlayerListEventListeners (removeEl = true) {
document.querySelectorAll('.game-player').forEach((el) => {
const pointer = el.dataset.pointer;
if (pointer && this.killPlayerHandlers[pointer]) {
el.removeEventListener('click', this.killPlayerHandlers[pointer]);
delete this.killPlayerHandlers[pointer];
}
if (pointer && this.revealRoleHandlers[pointer]) {
el.removeEventListener('click', this.revealRoleHandlers[pointer]);
delete this.revealRoleHandlers[pointer];
}
if (removeEl) {
el.remove();
}
});
}
renderPlayersWithNoRoleInformationUnlessRevealed (tempMod = false) { renderPlayersWithNoRoleInformationUnlessRevealed (tempMod = false) {
if (tempMod) { if (tempMod) {
document.querySelectorAll('.game-player').forEach((el) => { this.removePlayerListEventListeners();
const pointer = el.dataset.pointer;
if (pointer && this.killPlayerHandlers[pointer]) {
el.removeEventListener('click', this.killPlayerHandlers[pointer]);
delete this.killPlayerHandlers[pointer];
}
if (pointer && this.revealRoleHandlers[pointer]) {
el.removeEventListener('click', this.revealRoleHandlers[pointer]);
delete this.revealRoleHandlers[pointer];
}
el.remove();
});
} }
document.querySelectorAll('.game-player').forEach((el) => el.remove()); document.querySelectorAll('.game-player').forEach((el) => el.remove());
/* TODO: UX issue - it's easier to parse visually when players are sorted this way, /* TODO: UX issue - it's easier to parse visually when players are sorted this way,
but shifting players around when they are killed or revealed is bad UX for the moderator. */ but shifting players around when they are killed or revealed is bad UX for the moderator. */
// sortPeopleByStatus(this.stateBucket.currentGameState.people); // sortPeopleByStatus(this.stateBucket.currentGameState.people);
const modType = tempMod ? this.stateBucket.currentGameState.moderator.userType : null; const modType = tempMod ? this.stateBucket.currentGameState.moderator.userType : null;
renderGroupOfPlayers( this.renderGroupOfPlayers(
this.stateBucket.currentGameState.people, this.stateBucket.currentGameState.people,
this.killPlayerHandlers, this.killPlayerHandlers,
this.revealRoleHandlers, this.revealRoleHandlers,
@@ -305,6 +311,81 @@ export class GameStateRenderer {
} }
this.renderPlayersWithNoRoleInformationUnlessRevealed(); this.renderPlayersWithNoRoleInformationUnlessRevealed();
} }
renderGroupOfPlayers (
people,
killPlayerHandlers,
revealRoleHandlers,
accessCode = null,
alignment = null,
moderatorType,
socket = null
) {
for (const player of people) {
const playerEl = document.createElement('div');
playerEl.classList.add('game-player');
// add a reference to the player's id for each corresponding element in the list
if (moderatorType) {
playerEl.dataset.pointer = player.id;
playerEl.innerHTML = HTMLFragments.MODERATOR_PLAYER;
} else {
playerEl.innerHTML = HTMLFragments.GAME_PLAYER;
}
playerEl.querySelector('.game-player-name').innerText = player.name;
const roleElement = playerEl.querySelector('.game-player-role');
// Add role/alignment indicators if necessary
if (moderatorType === globals.USER_TYPES.MODERATOR || player.revealed || this.stateBucket.currentGameState.status === globals.STATUS.ENDED) {
if (alignment === null) {
roleElement.classList.add(player.alignment);
} else {
roleElement.classList.add(alignment);
}
roleElement.innerText = player.gameRole;
} else {
roleElement.innerText = 'Role Unknown';
}
// Change element based on player's in/out status
if (player.out) {
playerEl.classList.add('killed');
if (moderatorType) {
playerEl.querySelector('.kill-player-button')?.remove();
insertPlaceholderButton(playerEl, false, 'killed');
}
} else if (!player.out && moderatorType) {
killPlayerHandlers[player.id] = () => {
if (confirm('KILL ' + player.name + '?')) {
socket.emit(globals.COMMANDS.KILL_PLAYER, accessCode, player.id);
}
};
playerEl.querySelector('.kill-player-button').addEventListener('click', killPlayerHandlers[player.id]);
}
// change element based on player's revealed/unrevealed status
if (player.revealed) {
if (moderatorType) {
playerEl.querySelector('.reveal-role-button')?.remove();
insertPlaceholderButton(playerEl, true, 'revealed');
}
} else if (!player.revealed && moderatorType) {
revealRoleHandlers[player.id] = () => {
if (confirm('REVEAL ' + player.name + '?')) {
socket.emit(globals.COMMANDS.REVEAL_PLAYER, accessCode, player.id);
}
};
playerEl.querySelector('.reveal-role-button').addEventListener('click', revealRoleHandlers[player.id]);
}
const playerListContainerId = moderatorType === globals.USER_TYPES.MODERATOR
? 'player-list-moderator-team-' + alignment
: 'game-player-list';
document.getElementById(playerListContainerId).appendChild(playerEl);
}
}
} }
function renderPotentialMods (gameState, group, transferModHandlers, socket) { function renderPotentialMods (gameState, group, transferModHandlers, socket) {
@@ -365,86 +446,6 @@ function removeExistingTitle () {
} }
} }
// TODO: refactor to reduce the cyclomatic complexity of this function
function renderGroupOfPlayers (
people,
killPlayerHandlers,
revealRoleHandlers,
accessCode = null,
alignment = null,
moderatorType,
socket = null
) {
for (const player of people) {
const container = document.createElement('div');
container.classList.add('game-player');
if (moderatorType) {
container.dataset.pointer = player.id;
container.innerHTML = HTMLFragments.MODERATOR_PLAYER;
} else {
container.innerHTML = HTMLFragments.GAME_PLAYER;
}
container.querySelector('.game-player-name').innerText = player.name;
const roleElement = container.querySelector('.game-player-role');
if (moderatorType) {
roleElement.classList.add(alignment);
if (moderatorType === globals.USER_TYPES.MODERATOR) {
roleElement.innerText = player.gameRole;
document.getElementById('player-list-moderator-team-' + alignment).appendChild(container);
} else {
if (player.revealed) {
roleElement.innerText = player.gameRole;
roleElement.classList.add(player.alignment);
} else {
roleElement.innerText = 'Unknown';
}
document.getElementById('game-player-list').appendChild(container);
}
} else if (player.revealed) {
roleElement.classList.add(player.alignment);
roleElement.innerText = player.gameRole;
document.getElementById('game-player-list').appendChild(container);
} else {
roleElement.innerText = 'Unknown';
document.getElementById('game-player-list').appendChild(container);
}
if (player.out) {
container.classList.add('killed');
if (moderatorType) {
container.querySelector('.kill-player-button')?.remove();
insertPlaceholderButton(container, false, 'killed');
}
} else {
if (moderatorType) {
killPlayerHandlers[player.id] = () => {
if (confirm('KILL ' + player.name + '?')) {
socket.emit(globals.COMMANDS.KILL_PLAYER, accessCode, player.id);
}
};
container.querySelector('.kill-player-button').addEventListener('click', killPlayerHandlers[player.id]);
}
}
if (player.revealed) {
if (moderatorType) {
container.querySelector('.reveal-role-button')?.remove();
insertPlaceholderButton(container, true, 'revealed');
}
} else {
if (moderatorType) {
revealRoleHandlers[player.id] = () => {
if (confirm('REVEAL ' + player.name + '?')) {
socket.emit(globals.COMMANDS.REVEAL_PLAYER, accessCode, player.id);
}
};
container.querySelector('.reveal-role-button').addEventListener('click', revealRoleHandlers[player.id]);
}
}
}
}
function renderPlayerRole (gameState) { function renderPlayerRole (gameState) {
const name = document.querySelector('#role-name'); const name = document.querySelector('#role-name');
name.innerText = gameState.client.gameRole; name.innerText = gameState.client.gameRole;

View File

@@ -261,7 +261,7 @@ function setClientSocketHandlers (stateBucket, gameStateRenderer, socket, timerW
toast(killedPerson.name + ' was killed!', 'warning', true, true, 'medium'); toast(killedPerson.name + ' was killed!', 'warning', true, true, 'medium');
} }
if (stateBucket.currentGameState.client.userType === globals.USER_TYPES.TEMPORARY_MODERATOR) { if (stateBucket.currentGameState.client.userType === globals.USER_TYPES.TEMPORARY_MODERATOR) {
gameStateRenderer.renderPlayersWithNoRoleInformationUnlessRevealed(true); gameStateRenderer.removePlayerListEventListeners(false);
} else { } else {
gameStateRenderer.renderPlayersWithNoRoleInformationUnlessRevealed(false); gameStateRenderer.renderPlayersWithNoRoleInformationUnlessRevealed(false);
} }

View File

@@ -321,7 +321,7 @@ input {
align-items: center; align-items: center;
justify-content: center; justify-content: center;
position: fixed; position: fixed;
z-index: 55000; z-index: 1000000;
padding: 10px; padding: 10px;
border-radius: 3px; border-radius: 3px;
font-family: 'signika-negative', sans-serif; font-family: 'signika-negative', sans-serif;

View File

@@ -84,7 +84,7 @@
<div class="how-to-use-section"> <div class="how-to-use-section">
This is an example of what a <span class="emphasized">dedicated moderator</span> sees during the game: This is an example of what a <span class="emphasized">dedicated moderator</span> sees during the game:
<br><br> <br><br>
<img class='tutorial-image-small' src="../images/tutorial/moderator-view.PNG"/> <img class='tutorial-image-small' src="../images/tutorial/dedicated-mod.PNG"/>
<br><br> <br><br>
They can see who is on which team and who has each role. The moderator kills and reveals players. They are They can see who is on which team and who has each role. The moderator kills and reveals players. They are
separate actions - note the two buttons for each player. So if you want to play a game where people's roles are separate actions - note the two buttons for each player. So if you want to play a game where people's roles are
@@ -96,7 +96,7 @@
much the same abilities as a dedicated moderator, except they don't know role or alignment information and cannot much the same abilities as a dedicated moderator, except they don't know role or alignment information and cannot
transfer their powers. Their powers will be transferred automatically to the first person they remove from the game: transfer their powers. Their powers will be transferred automatically to the first person they remove from the game:
<br><br> <br><br>
<img class='tutorial-image-small' src="../images/tutorial/temp-mod-view.PNG"/> <img class='tutorial-image-small' src="../images/tutorial/temporary-mod.PNG"/>
<br><br> <br><br>
<h3>Transferring your moderator powers</h3> <h3>Transferring your moderator powers</h3>
<br> <br>