mirror of
https://github.com/openfrontio/OpenFrontIO.git
synced 2026-06-23 00:15:23 +00:00
thread-split: create PlayerProfile transfer flow
This commit is contained in:
@@ -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`<div class="type-label">Attitude: <span class="${classType}">${relationName}</span></div>`;
|
||||
relationHtml = html`<div class="type-label">Attitude: <span class="${classType}">${relationName}</span></div>`;
|
||||
}
|
||||
return html`
|
||||
<div class="info-content">
|
||||
<div class="player-name ${isAlly ? 'ally' : ''}">${player.name()}</div>
|
||||
<div class="type-label">Troops: ${renderTroops(player.troops())}</div>
|
||||
<div class="type-label">Gold: ${renderNumber(player.gold())}</div>
|
||||
${relation == null ? '' : relation}
|
||||
${relationHtml == null ? '' : relationHtml}
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
+11
-2
@@ -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 {
|
||||
|
||||
@@ -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<PlayerProfile> {
|
||||
return this.game.worker.playerProfile(this.smallID())
|
||||
}
|
||||
|
||||
allRelationsSorted(): { player: Player; relation: Relation; }[] {
|
||||
return []
|
||||
}
|
||||
|
||||
@@ -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<MainThreadMessage>) => {
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -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> {
|
||||
playerProfile(playerID: number): Promise<PlayerProfile> {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (!this.isInitialized) {
|
||||
reject(new Error('Worker not initialized'));
|
||||
|
||||
Reference in New Issue
Block a user