diff --git a/TODO.txt b/TODO.txt index 2a90746b3..bae144a32 100644 --- a/TODO.txt +++ b/TODO.txt @@ -219,19 +219,21 @@ * add Oceania map DONE 12/8/2023 * max price for units DONE 12/9/2024 * better unit scaling DONE 12/9/2024 +* make hard & impossible harder DONE 12/9/2024 * store in BigQuery -* make hard & impossible harder * clicking on a player's name in the rank UI should teleport you to him (pretty useful to know who's who and to locate small nations) -* record commit hash of game +* make boats work on lakes (& oceania) * record game winner * add panama canal NA -* make boats work on lakes (& oceania) * replay stored games +* record commit hash of game * when player dies, don't remove atom bombs * remove alliance when player dies * only check islands/clusters when being attacked * alert on attack * alert on unit captured or destroyed +* put delay on adjust troop ratio to reduce number of messages +* make clientID & playerID smaller * nuking an enemy and accidentally destroying a trade ship shouldn't break the alliance and make you a traitor * you should get a notification and a reward (some money) for eliminating an enemy (perhaps take wtvr gold the enemy had) * emojis should be displayed on top of your name not under it diff --git a/src/client/graphics/GameRenderer.ts b/src/client/graphics/GameRenderer.ts index 5412ac305..a2c5cff97 100644 --- a/src/client/graphics/GameRenderer.ts +++ b/src/client/graphics/GameRenderer.ts @@ -41,6 +41,7 @@ export function createRenderer(canvas: HTMLCanvasElement, game: Game, eventBus: console.error('EmojiTable element not found in the DOM'); } leaderboard.clientID = clientID + leaderboard.eventBus = eventBus const controlPanel = document.querySelector('control-panel') as ControlPanel; diff --git a/src/client/graphics/TransformHandler.ts b/src/client/graphics/TransformHandler.ts index 299423d5e..0d3caa833 100644 --- a/src/client/graphics/TransformHandler.ts +++ b/src/client/graphics/TransformHandler.ts @@ -1,6 +1,7 @@ -import {EventBus} from "../../core/EventBus" -import {Cell, Game} from "../../core/game/Game"; -import {ZoomEvent, DragEvent} from "../InputHandler"; +import { EventBus } from "../../core/EventBus" +import { Cell, Game } from "../../core/game/Game"; +import { ZoomEvent, DragEvent } from "../InputHandler"; +import { GoToPlayerEvent } from "./layers/Leaderboard"; export class TransformHandler { public scale: number = 1.8 @@ -10,6 +11,7 @@ export class TransformHandler { constructor(private game: Game, private eventBus: EventBus, private canvas: HTMLCanvasElement) { this.eventBus.on(ZoomEvent, (e) => this.onZoom(e)) this.eventBus.on(DragEvent, (e) => this.onMove(e)) + this.eventBus.on(GoToPlayerEvent, (e) => this.onGoToPlayer(e)) } boundingRect(): DOMRect { @@ -53,7 +55,6 @@ export class TransformHandler { screenBoundingRect(): [Cell, Cell] { - // Calculate the world point we want to zoom towards const LeftX = (- this.game.width() / 2) / this.scale + this.offsetX; const TopY = (- this.game.height() / 2) / this.scale + this.offsetY; @@ -61,7 +62,6 @@ export class TransformHandler { const gameTopY = TopY + this.game.height() / 2 - // Calculate the world point we want to zoom towards const rightX = (screen.width - this.game.width() / 2) / this.scale + this.offsetX; const rightY = (screen.height - this.game.height() / 2) / this.scale + this.offsetY; @@ -71,6 +71,18 @@ export class TransformHandler { return [new Cell(Math.floor(gameLeftX), Math.floor(gameTopY)), new Cell(Math.floor(gameRightX), Math.floor(gameBottomY))] } + screenCenter(): Cell { + const [upperLeft, bottomRight] = this.screenBoundingRect() + return new Cell( + Math.floor((bottomRight.x - upperLeft.x) / 2), + Math.floor((bottomRight.y - upperLeft.y) / 2) + ) + } + + onGoToPlayer(event: GoToPlayerEvent) { + + } + onZoom(event: ZoomEvent) { const oldScale = this.scale; const zoomFactor = 1 + event.delta / 600; diff --git a/src/client/graphics/layers/Leaderboard.ts b/src/client/graphics/layers/Leaderboard.ts index 8372b661c..5b30a020f 100644 --- a/src/client/graphics/layers/Leaderboard.ts +++ b/src/client/graphics/layers/Leaderboard.ts @@ -4,12 +4,18 @@ import { Layer } from './Layer'; import { Game, Player } from '../../../core/game/Game'; import { ClientID } from '../../../core/Schemas'; import { unsafeHTML } from 'lit/directives/unsafe-html.js'; +import { EventBus, GameEvent } from '../../../core/EventBus'; interface Entry { name: string position: number score: string isMyPlayer: boolean + player: Player +} + +export class GoToPlayerEvent implements GameEvent { + constructor(public player: Player) { } } @customElement('leader-board') @@ -17,6 +23,7 @@ export class Leaderboard extends LitElement implements Layer { private game: Game public clientID: ClientID + public eventBus: EventBus init(game: Game) { this.game = game @@ -51,7 +58,8 @@ export class Leaderboard extends LitElement implements Layer { name: player.displayName(), position: index + 1, score: formatPercentage(player.numTilesOwned() / this.game.numLandTiles()), - isMyPlayer: player == myPlayer + isMyPlayer: player == myPlayer, + player: player })); if (myPlayer != null && this.players.find(p => p.isMyPlayer) == null) { @@ -69,13 +77,17 @@ export class Leaderboard extends LitElement implements Layer { position: place, score: formatPercentage(myPlayer.numTilesOwned() / this.game.numLandTiles()), isMyPlayer: true, + player: myPlayer }) } - this.requestUpdate() } + private handleRowClick(player: Player) { + this.eventBus.emit(new GoToPlayerEvent(player)) + } + renderLayer(context: CanvasRenderingContext2D) { } shouldTransform(): boolean { @@ -87,15 +99,15 @@ export class Leaderboard extends LitElement implements Layer { display: block; } img.emoji { - height: 1em; // Match text height - width: auto; // Maintain aspect ratio + height: 1em; + width: auto; } .leaderboard { position: fixed; top: 10px; left: 10px; z-index: 9999; - background-color: rgba(30, 30, 30, 0.7); /* Added transparency */ + background-color: rgba(30, 30, 30, 0.7); padding: 10px; box-shadow: 0 0 20px rgba(0, 0, 0, 0.5); border-radius: 10px; @@ -103,7 +115,7 @@ export class Leaderboard extends LitElement implements Layer { max-height: 80vh; overflow-y: auto; width: 300px; - backdrop-filter: blur(5px); /* Optional: adds a blur effect to content behind the leaderboard */ + backdrop-filter: blur(5px); } table { width: 100%; @@ -112,11 +124,11 @@ export class Leaderboard extends LitElement implements Layer { th, td { padding: 8px; text-align: left; - border-bottom: 1px solid rgba(51, 51, 51, 0.2); /* Made border slightly transparent */ + border-bottom: 1px solid rgba(51, 51, 51, 0.2); color: white; } th { - background-color: rgba(44, 44, 44, 0.5); /* Made header slightly transparent */ + background-color: rgba(44, 44, 44, 0.5); color: white; } .myPlayer { @@ -127,10 +139,14 @@ export class Leaderboard extends LitElement implements Layer { font-size: 1.3em; } tr:nth-child(even) { - background-color: rgba(44, 44, 44, 0.5); /* Made alternating rows slightly transparent */ + background-color: rgba(44, 44, 44, 0.5); } - tr:hover { - background-color: rgba(58, 58, 58, 0.6); /* Made hover effect slightly transparent */ + tbody tr { + cursor: pointer; + transition: background-color 0.2s; + } + tbody tr:hover { + background-color: rgba(78, 78, 78, 0.8); } .hidden { display: none !important; @@ -160,8 +176,11 @@ export class Leaderboard extends LitElement implements Layer {
${this.players - .map((player, index) => html` -