From 6f1848dbc7d56279070e3def4dbf7bc073aa16da Mon Sep 17 00:00:00 2001 From: evanpelle Date: Sun, 25 Aug 2024 09:33:58 -0700 Subject: [PATCH] can leave lobby --- TODO.txt | 1 + src/client/Client.ts | 76 +++++++++++-------------- src/client/ClientGame.ts | 4 ++ src/client/index.html | 47 ++++++--------- src/core/configuration/DefaultConfig.ts | 4 +- src/core/configuration/DevConfig.ts | 8 +-- src/server/GameServer.ts | 1 + 7 files changed, 61 insertions(+), 80 deletions(-) diff --git a/TODO.txt b/TODO.txt index d12553cb0..51f7947d8 100644 --- a/TODO.txt +++ b/TODO.txt @@ -54,3 +54,4 @@ * BUG: fix hotreload (priority queue breaks it) * PERF: use hierarchical a* search for boats * Add terrain elevation to map +* boats can go around the world \ No newline at end of file diff --git a/src/client/Client.ts b/src/client/Client.ts index e0d2c8917..9c49f052c 100644 --- a/src/client/Client.ts +++ b/src/client/Client.ts @@ -24,6 +24,7 @@ class Client { private lobbiesContainer: HTMLElement | null; private lobbiesInterval: NodeJS.Timeout | null = null; + private isLobbyHighlighted: boolean = false; private random = new PseudoRandom(1234) @@ -52,34 +53,31 @@ class Client { } private updateLobbiesDisplay(lobbies: Lobby[]): void { - if (!this.lobbiesContainer) return; + if (lobbies.length === 0) { + document.getElementById('lobby-button').style.display = 'none'; + return; + } - this.lobbiesContainer.innerHTML = ''; // Clear existing lobbies + const lobby = lobbies[0]; + const lobbyButton = document.getElementById('lobby-button'); + const nameElement = document.getElementById('lobby-name'); + const timerElement = document.getElementById('lobby-timer'); + const playerCountElement = document.getElementById('player-count'); - lobbies.forEach(lobby => { - const button = document.createElement('button'); - button.className = 'lobby-button'; + if (lobbyButton) { + lobbyButton.style.display = 'flex'; + lobbyButton.onclick = () => this.joinLobby(lobby); - const nameElement = document.createElement('div'); - nameElement.className = 'lobby-name'; - nameElement.textContent = `Lobby ${lobby.id}`; + // Preserve the highlighted state + lobbyButton.classList.toggle('highlighted', this.isLobbyHighlighted); + } - const timerElement = document.createElement('div'); - timerElement.className = 'lobby-timer'; + if (nameElement) nameElement.textContent = `Lobby ${lobby.id}`; + if (timerElement) { const timeRemaining = Math.max(0, Math.floor((lobby.startTime - Date.now()) / 1000)); timerElement.textContent = `Starts in: ${timeRemaining}s`; - - const playerCountElement = document.createElement('div'); - playerCountElement.className = 'player-count'; - playerCountElement.textContent = `Players: ${lobby.numClients}` - - button.appendChild(nameElement); - button.appendChild(timerElement); - button.appendChild(playerCountElement); - - button.onclick = () => this.joinLobby(lobby); - this.lobbiesContainer.appendChild(button); - }); + } + if (playerCountElement) playerCountElement.textContent = `Players: ${lobby.numClients}`; } async fetchLobbies(): Promise { @@ -97,25 +95,16 @@ class Client { } } - private async joinLobby(lobby: Lobby) { - clearInterval(this.lobbiesInterval); - - if (this.lobbiesContainer) { - // Clear existing content - this.lobbiesContainer.innerHTML = ''; - - // Ensure the container takes up the full height of the viewport - this.lobbiesContainer.style.display = 'flex'; - this.lobbiesContainer.style.justifyContent = 'center'; - this.lobbiesContainer.style.alignItems = 'center'; - this.lobbiesContainer.style.minHeight = '100vh'; - - // Create and add the joining message - const joiningMessage = document.createElement('div'); - joiningMessage.textContent = `Joining: ${lobby.id}`; - joiningMessage.className = 'joining-message'; - - this.lobbiesContainer.appendChild(joiningMessage); + private joinLobby(lobby: Lobby) { + const lobbyButton = document.getElementById('lobby-button'); + if (lobbyButton) { + this.isLobbyHighlighted = !this.isLobbyHighlighted; + lobbyButton.classList.toggle('highlighted', this.isLobbyHighlighted); + } + if (!this.isLobbyHighlighted) { + this.game.stop() + this.game = null + return } if (this.game != null) { @@ -123,11 +112,10 @@ class Client { } this.game = createClientGame(getUsername(), new PseudoRandom(Date.now()).nextID(), lobby.id, getConfig(), this.terrainMap); this.game.join(); - const g = this.game + const g = this.game; window.addEventListener('beforeunload', function (event) { - // Your function logic here console.log('Browser is closing'); - g.stop() + g.stop(); }); } } diff --git a/src/client/ClientGame.ts b/src/client/ClientGame.ts index 02d37b8aa..d7b943ed1 100644 --- a/src/client/ClientGame.ts +++ b/src/client/ClientGame.ts @@ -97,6 +97,9 @@ export class ClientGame { }; this.socket.onclose = (event: CloseEvent) => { console.log(`WebSocket closed. Code: ${event.code}, Reason: ${event.reason}`); + if (!this.isActive) { + return + } if (event.code != 1000) { this.join() } @@ -126,6 +129,7 @@ export class ClientGame { clearInterval(this.intervalID) this.isActive = false if (this.socket.readyState === WebSocket.OPEN) { + console.log('on stop: leaving game') const msg = ClientLeaveMessageSchema.parse({ type: "leave", clientID: this.id, diff --git a/src/client/index.html b/src/client/index.html index be2667af0..7fe9f640a 100644 --- a/src/client/index.html +++ b/src/client/index.html @@ -5,7 +5,7 @@ OpenFront (ALPHA) - + @@ -136,7 +119,11 @@
- +
diff --git a/src/core/configuration/DefaultConfig.ts b/src/core/configuration/DefaultConfig.ts index 57a5ec381..8abd75eae 100644 --- a/src/core/configuration/DefaultConfig.ts +++ b/src/core/configuration/DefaultConfig.ts @@ -71,11 +71,11 @@ export class DefaultPlayerConfig implements PlayerConfig { } troopAdditionRate(player: Player): number { - const max = Math.sqrt(player.numTilesOwned()) * 1000 + 1000 + const max = Math.sqrt(player.numTilesOwned()) * 1000 + 10000 let toAdd = 10 + (player.troops() + Math.sqrt(player.troops() * player.numTilesOwned())) / 250 - return Math.min(player.troops() + toAdd, max) + return Math.min(Math.min(player.troops() + toAdd, max), 1_000_0000) } } diff --git a/src/core/configuration/DevConfig.ts b/src/core/configuration/DevConfig.ts index 323ab22c7..f814657f0 100644 --- a/src/core/configuration/DevConfig.ts +++ b/src/core/configuration/DevConfig.ts @@ -4,10 +4,10 @@ import {DefaultConfig, DefaultPlayerConfig, defaultPlayerConfig} from "./Default export const devConfig = new class extends DefaultConfig { gameCreationRate(): number { - return 2 * 1000 + return 21 * 1000 } lobbyLifetime(): number { - return 5 * 1000 + return 20 * 1000 } turnIntervalMs(): number { return 100 @@ -16,7 +16,7 @@ export const devConfig = new class extends DefaultConfig { return devPlayerConfig } numBots(): number { - return 500 + return 250 } } @@ -25,6 +25,6 @@ export const devPlayerConfig = new class extends DefaultPlayerConfig { if (playerInfo.isBot) { return 5000 } - return 5000 + return 10000 } } \ No newline at end of file diff --git a/src/server/GameServer.ts b/src/server/GameServer.ts index ebea84eeb..d5c6ded96 100644 --- a/src/server/GameServer.ts +++ b/src/server/GameServer.ts @@ -43,6 +43,7 @@ export class GameServer { } } if (clientMsg.type == "leave") { + // TODO: get rid of leave message, just use on close? const toRemove = this.clients.filter(c => c.id) if (toRemove.length == 0) { return