diff --git a/src/client/graphics/layers/PlayerInfoOverlay.ts b/src/client/graphics/layers/PlayerInfoOverlay.ts index 42781bd92..25320adb0 100644 --- a/src/client/graphics/layers/PlayerInfoOverlay.ts +++ b/src/client/graphics/layers/PlayerInfoOverlay.ts @@ -1,7 +1,7 @@ import { LitElement, html, css } from 'lit'; import { customElement, property, state } from 'lit/decorators.js'; import { Layer } from './Layer'; -import { Game, GameType, Player, PlayerType, Relation, Unit, UnitType } from '../../../core/game/Game'; +import { Game, GameType, Player, PlayerProfile, PlayerType, Relation, Unit, UnitType } from '../../../core/game/Game'; import { ClientID } from '../../../core/Schemas'; import { EventBus } from '../../../core/EventBus'; import { TransformHandler } from '../TransformHandler'; @@ -9,7 +9,7 @@ import { MouseMoveEvent } from '../../InputHandler'; import { euclideanDist, distSortUnit } from '../../../core/Util'; import { renderNumber, renderTroops } from '../../Utils'; import { PauseGameEvent } from '../../Transport'; -import { GameView } from '../../../core/GameView'; +import { GameView, PlayerView } from '../../../core/GameView'; @customElement('player-info-overlay') export class PlayerInfoOverlay extends LitElement implements Layer { @@ -28,6 +28,9 @@ export class PlayerInfoOverlay extends LitElement implements Layer { @state() private player: Player | null = null; + @state() + private playerProfile: PlayerProfile | null = null + @state() private unit: Unit | null = null; @@ -51,6 +54,7 @@ export class PlayerInfoOverlay extends LitElement implements Layer { private onMouseEvent(event: MouseMoveEvent) { this.setVisible(false); this.unit = null; + const lastPlayer = this.player this.player = null; const worldCoord = this.transform.screenToWorldCoordinates(event.x, event.y); @@ -63,6 +67,10 @@ export class PlayerInfoOverlay extends LitElement implements Layer { if (owner.isPlayer()) { this.player = owner; + (this.player as PlayerView).profile().then(p => { + console.log(`got profile ${JSON.stringify(p)}`) + this.playerProfile = p + }) this.setVisible(true); } else if (!tile.terrain().isLand()) { const units = this.game.units(UnitType.Destroyer, UnitType.Battleship, UnitType.TradeShip) @@ -112,11 +120,12 @@ export class PlayerInfoOverlay extends LitElement implements Layer { private renderPlayerInfo(player: Player) { const myPlayer = this.myPlayer(); const isAlly = (myPlayer?.isAlliedWith(player) || player == this.myPlayer()) ?? false; - let relation = null + let relationHtml = null if (player.type() == PlayerType.FakeHuman && myPlayer != null) { let classType = '' let relationName = '' - switch (player.relation(myPlayer)) { + const relation = this.playerProfile?.relations[myPlayer.smallID()] ?? Relation.Neutral + switch (relation) { case Relation.Hostile: classType = 'hostile' relationName = 'Hostile' @@ -135,14 +144,14 @@ export class PlayerInfoOverlay extends LitElement implements Layer { break } - relation = html`
Attitude: ${relationName}
`; + relationHtml = html`
Attitude: ${relationName}
`; } return html`
${player.name()}
Troops: ${renderTroops(player.troops())}
Gold: ${renderNumber(player.gold())}
- ${relation == null ? '' : relation} + ${relationHtml == null ? '' : relationHtml}
`; } diff --git a/src/core/GameRunner.ts b/src/core/GameRunner.ts index 4f45dcc7e..b3a868fa3 100644 --- a/src/core/GameRunner.ts +++ b/src/core/GameRunner.ts @@ -105,10 +105,19 @@ export class GameRunner { return actions } + public playerProfile(playerID: number): PlayerProfile { - return { - relations: this.game.players().filter(p => p.smallID() == playerID)[0]?.allRelationsSorted() + const player = this.game.players().filter(p => p.smallID() == playerID)[0]; + if (!player) { + throw new Error(`player with id ${playerID} not found`); } + + return { + relations: Object.fromEntries( + player.allRelationsSorted() + .map(({ player, relation }) => [player.smallID(), relation]) + ) + }; } private canBoat(myPlayer: Player, tile: Tile): boolean { diff --git a/src/core/GameView.ts b/src/core/GameView.ts index c6f39c222..02bd9851f 100644 --- a/src/core/GameView.ts +++ b/src/core/GameView.ts @@ -1,4 +1,4 @@ -import { GameUpdates, GameUpdateType, MapPos, MessageType, NameViewData, Player, PlayerActions, PlayerUpdate, Tile, TileUpdate, Unit, UnitUpdate } from './game/Game'; +import { GameUpdates, GameUpdateType, MapPos, MessageType, NameViewData, Player, PlayerActions, PlayerProfile, PlayerUpdate, Tile, TileUpdate, Unit, UnitUpdate } from './game/Game'; import { Config } from "./configuration/Config"; import { Alliance, AllianceRequest, AllPlayers, Cell, DefenseBonus, EmojiMessage, Execution, ExecutionView, Game, Gold, MutableTile, Nation, PlayerID, PlayerInfo, PlayerType, Relation, TerrainMap, TerrainTile, TerrainType, TerraNullius, Tick, UnitInfo, UnitType } from "./game/Game"; import { ClientID } from "./Schemas"; @@ -205,6 +205,11 @@ export class PlayerView implements Player { relation(other: Player): Relation { return Relation.Neutral } + + profile(): Promise { + return this.game.worker.playerProfile(this.smallID()) + } + allRelationsSorted(): { player: Player; relation: Relation; }[] { return [] } diff --git a/src/core/worker/Worker.worker.ts b/src/core/worker/Worker.worker.ts index 9f7ec81ff..e8a3ddd43 100644 --- a/src/core/worker/Worker.worker.ts +++ b/src/core/worker/Worker.worker.ts @@ -5,6 +5,7 @@ import { WorkerMessage, InitializedMessage, PlayerActionsResultMessage, + PlayerProfileResultMessage, } from './WorkerMessages'; const ctx: Worker = self as any; @@ -83,19 +84,17 @@ ctx.addEventListener('message', async (e: MessageEvent) => { } try { - const actions = (await gameRunner).playerActions(message.playerID, message.x, message.y) + const profile = (await gameRunner).playerProfile(message.playerID) sendMessage({ - type: 'player_actions_result', + type: 'player_profile_result', id: message.id, - result: actions - } as PlayerActionsResultMessage); + result: profile + } as PlayerProfileResultMessage); } catch (error) { console.error('Failed to check borders:', error); throw error; } break; - - default: console.warn('Unknown message :', message); } diff --git a/src/core/worker/WorkerClient.ts b/src/core/worker/WorkerClient.ts index 8e6da0acb..bad808697 100644 --- a/src/core/worker/WorkerClient.ts +++ b/src/core/worker/WorkerClient.ts @@ -29,7 +29,7 @@ export class WorkerClient { break; case 'initialized': - case 'player_actions_result': + default: if (message.id && this.messageHandlers.has(message.id)) { const handler = this.messageHandlers.get(message.id)!; handler(message); @@ -91,7 +91,7 @@ export class WorkerClient { }); } - playerInfo(playerID: number): Promise { + playerProfile(playerID: number): Promise { return new Promise((resolve, reject) => { if (!this.isInitialized) { reject(new Error('Worker not initialized'));