Show win counts in the lobby too

This commit is contained in:
Andrio Celos 2023-08-13 22:49:27 +10:00
parent dcb669490c
commit 235d3ac25a
7 changed files with 103 additions and 69 deletions

View File

@ -78,7 +78,7 @@
<form id="stageSelectionForm">
<div class="submitButtonContainer">
<button type="submit" id="submitStageButton">Submit</button>
<div class="loadingContainer">
<div class="loadingContainer" hidden>
<div class="loadingSpinner"></div>
</div>
</div>

View File

@ -274,7 +274,7 @@ replayPreviousButton.buttonElement.addEventListener('click', _ => {
for (let i = 0; i < currentGame.players.length; i++) {
if (currentReplay.games[currentReplay.gameNumber].playerData[i].won)
currentGame.players[i].gamesWon--;
playerBars[i].wins = currentGame.players[i].gamesWon;
playerBars[i].winCounter.wins = currentGame.players[i].gamesWon;
}
}
@ -359,7 +359,7 @@ function replaySwitchGame(gameNumber: number) {
if (currentReplay.games[j].playerData[i].won)
currentGame.players[i].gamesWon++;
}
playerBars[i].wins = currentGame.players[i].gamesWon;
playerBars[i].winCounter.wins = currentGame.players[i].gamesWon;
}
currentReplay.gameNumber = gameNumber;
@ -510,7 +510,7 @@ function loadPlayers(players: Player[]) {
const player = players[i];
currentGame!.players[i] = players[i];
playerBars[i].name = player.name;
playerBars[i].wins = players[i].gamesWon;
playerBars[i].winCounter.wins = players[i].gamesWon;
updateStats(i, scores);
if (player.colour.r || player.colour.g || player.colour.b) {
document.body.style.setProperty(`--primary-colour-${i + 1}`, `rgb(${player.colour.r}, ${player.colour.g}, ${player.colour.b})`);
@ -676,7 +676,7 @@ function showResult() {
el.classList.remove('lose');
el.classList.remove('draw');
el.innerText = 'Victory';
playerBars[i].wins++;
playerBars[i].winCounter.wins++;
} else {
el.classList.remove('win');
el.classList.remove('lose');

View File

@ -1,3 +1,5 @@
const lobbyWinCounters: WinCounter[] = [ ];
const stageButtons = new CheckButtonGroup<Stage>(document.getElementById('stageList')!);
const shareLinkButton = document.getElementById('shareLinkButton') as HTMLButtonElement;
const showQrCodeButton = document.getElementById('showQrCodeButton') as HTMLButtonElement;
@ -38,8 +40,6 @@ function lobbyInitStageDatabase(stages: Stage[]) {
}
function initLobbyPage(url: string) {
stageSelectionFormSubmitButton.disabled = false;
stageSelectionFormLoadingSection.hidden = true;
lobbyShareData = { url: url, title: 'Tableturf Battle' };
if (navigator.canShare && navigator.canShare(lobbyShareData)) {
shareLinkButton.innerText = 'Share link';
@ -85,28 +85,54 @@ qrCodeDialog.addEventListener('click', e => {
// Background was clicked.
qrCodeDialog.close();
}
})
});
function clearReady() {
if (currentGame == null) return;
for (var i = 0; i < currentGame.players.length; i++) {
currentGame.players[i].isReady = false;
updatePlayerListItem(i);
function lobbyResetSlots() {
if (!currentGame) throw new Error('No current game');
for (const li of playerListItems)
playerList.removeChild(li);
playerListItems.splice(0);
lobbyWinCounters.splice(0);
for (let i = 0; i < currentGame.maxPlayers; i++) {
var el = document.createElement('li');
el.className = 'empty';
el.innerText = 'Waiting...';
playerListItems.push(el);
playerList.appendChild(el);
}
}
function updatePlayerListItem(playerIndex: number) {
const listItem = playerListItems[playerIndex];
if (!currentGame?.players || playerIndex >= currentGame.players.length) {
listItem.className = 'empty';
listItem.innerText = 'Waiting...';
} else {
const player = currentGame.players[playerIndex];
listItem.innerText = player.name;
listItem.className = player.isReady ? 'filled ready' : 'filled';
function clearReady() {
if (!currentGame) throw new Error('No current game');
stageSelectionFormSubmitButton.disabled = false;
stageSelectionFormLoadingSection.hidden = true;
for (var i = 0; i < currentGame.players.length; i++) {
currentGame.players[i].isReady = false;
playerListItems[i].className = 'filled';
}
}
function lobbyAddPlayer(playerIndex: number) {
if (!currentGame) throw new Error('No current game');
const listItem = playerListItems[playerIndex];
const player = currentGame.players[playerIndex];
listItem.innerText = player.name;
listItem.className = player.isReady ? 'filled ready' : 'filled';
const el = document.createElement('div');
el.className = 'wins';
el.title = 'Battles won';
listItem.appendChild(el);
const winCounter = new WinCounter(el);
winCounter.wins = currentGame.players[playerIndex].gamesWon;
lobbyWinCounters.push(winCounter);
}
function lobbySetReady(playerIndex: number) {
playerListItems[playerIndex].className = 'filled ready';
}
function initDeckSelection() {
const lastDeckName = localStorage.getItem('lastDeckName');

View File

@ -2,9 +2,9 @@ class PlayerBar {
readonly playerIndex: number;
readonly element: HTMLElement;
readonly winCounter: WinCounter;
private nameElement: HTMLElement;
private winsElement: HTMLElement;
private specialPointsContainer: HTMLElement;
private pointsElement: HTMLElement;
private pointsContainer: HTMLElement;
@ -16,15 +16,14 @@ class PlayerBar {
statSpecialPointsElement: HTMLElement;
statPassesElement: HTMLElement;
private _wins: number = 0;
constructor(element: HTMLDivElement) {
this.element = element;
this.playerIndex = parseInt(element.dataset.index!);
if (isNaN(this.playerIndex))
throw new Error('Missing player index');
this.winCounter = new WinCounter(element.getElementsByClassName('wins')[0] as HTMLDivElement);
this.nameElement = element.getElementsByClassName('name')[0] as HTMLElement;
this.winsElement = element.getElementsByClassName('wins')[0] as HTMLElement;
this.specialPointsContainer = element.getElementsByClassName('specialPoints')[0] as HTMLElement;
let pointsContainer: HTMLElement | null = null;
@ -51,23 +50,6 @@ class PlayerBar {
get name() { return this.nameElement.innerText; }
set name(value: string) { this.nameElement.innerText = value; }
get wins() { return this._wins; }
set wins(value: number) {
this._wins = value;
clearChildren(this.winsElement);
if (value) {
if (value < 5) {
for (let i = 0; i < value; i++) {
this.winsElement.appendChild(document.createElement('div'));
}
}
const el = document.createElement('div');
el.classList.add('winCount');
el.innerText = value.toString();
this.winsElement.appendChild(el);
}
}
get points() { return parseInt(this.pointsElement.innerText); }
set points(value: number) { this.pointsElement.innerText = value.toString(); }

View File

@ -0,0 +1,25 @@
class WinCounter {
readonly parent: HTMLElement;
private _wins: number = 0;
constructor(element: HTMLDivElement) {
this.parent = element;
}
get wins() { return this._wins; }
set wins(value: number) {
this._wins = value;
clearChildren(this.parent);
if (value) {
if (value < 5) {
for (let i = 0; i < value; i++) {
this.parent.appendChild(document.createElement('div'));
}
}
const el = document.createElement('div');
el.classList.add('winCount');
el.innerText = value.toString();
this.parent.appendChild(el);
}
}
}

View File

@ -249,16 +249,9 @@ function setupWebSocket(gameID: string) {
webSocket: webSocket
};
for (const li of playerListItems)
playerList.removeChild(li);
playerListItems.splice(0);
for (let i = 0; i < currentGame.maxPlayers; i++) {
var el = document.createElement('li');
playerListItems.push(el);
playerList.appendChild(el);
updatePlayerListItem(i);
}
lobbyResetSlots();
for (let i = 0; i < currentGame.players.length; i++)
lobbyAddPlayer(i);
lobbyTimeLimitBox.value = currentGame.turnTimeLimit?.toString() ?? '';
lobbyTimeLimitUnit.hidden = currentGame.turnTimeLimit == null;
@ -308,15 +301,14 @@ function setupWebSocket(gameID: string) {
case 'join':
if (payload.data.playerIndex == currentGame.players.length) {
currentGame.players.push(payload.data.player);
playerListItems[payload.data.playerIndex].innerText = payload.data.player.name;
updatePlayerListItem(payload.data.playerIndex);
lobbyAddPlayer(payload.data.playerIndex);
}
else
communicationError();
break;
case 'playerReady':
currentGame.players[payload.data.playerIndex].isReady = true;
updatePlayerListItem(payload.data.playerIndex);
lobbySetReady(payload.data.playerIndex);
if (payload.data.playerIndex == currentGame.me?.playerIndex) {
lobbyStageSection.hidden = true;
@ -351,6 +343,7 @@ function setupWebSocket(gameID: string) {
player.passes = payload.data.game.players[i].passes;
player.gamesWon = payload.data.game.players[i].gamesWon;
player.isReady = payload.data.game.players[i].isReady;
lobbyWinCounters[i].wins = player.gamesWon;
const move = payload.data.moves[i];
const button = new CardButton(move.card);

View File

@ -173,6 +173,27 @@ footer {
to { left: 0; }
}
.wins {
display: flex;
}
.wins > div {
display: inline-block;
background: url('assets/external/IconMedal_00.webp') center/cover;
width: 2em;
height: 2em;
}
.winCount {
font-size: larger;
text-align: center;
text-shadow: 0.1em 0.1em 0 black;
}
.winCount:not(:first-child) { display: none; }
#playerList .wins {
float: right;
margin-right: 1.5em;
}
#lobbyTimeLimitBox {
width: 8ch;
text-align: right;
@ -991,23 +1012,10 @@ dialog::backdrop {
to { left: 50%; top: 50%; right: 50%; bottom: 50%; background: var(--special-accent-colour); visibility: hidden; }
}
.wins {
#gamePage .wins {
float: right;
display: flex;
margin-top: 1.25em;
}
.wins > div {
display: inline-block;
background: url('assets/external/IconMedal_00.webp') center/cover;
width: 2em;
height: 2em;
}
.winCount {
font-size: larger;
text-align: center;
text-shadow: 0.1em 0.1em 0 black;
}
.winCount:not(:first-child) { display: none; }
.result {
font-family: 'Splatoon 1';