mirror of
https://github.com/openfrontio/OpenFrontIO.git
synced 2026-07-08 01:30:39 +00:00
refactor cosmetics out of PlayerInfo (#1299)
## Description: Remove Cosmetics from PlayerInfo. The game engine should have no knowledge of cosmetics since they shouldn't affect game play at all. Instead pass player cosmetics into the GameView. ## Please complete the following: - [x] I have added screenshots for all UI updates - [x] I process any text displayed to the user through translateText() and I've added it to the en.json file - [x] I have added relevant tests to the test directory - [x] I confirm I have thoroughly tested these changes and take full responsibility for any bugs introduced - [x] I understand that submitting code with bugs that could have been caught through manual testing blocks releases and new features for all contributors ## Please put your Discord username so you can be contacted if a bug or regression is found: evan
This commit is contained in:
@@ -150,9 +150,10 @@ export async function createClientGame(
|
||||
const gameView = new GameView(
|
||||
worker,
|
||||
config,
|
||||
gameMap.gameMap,
|
||||
gameMap,
|
||||
lobbyConfig.clientID,
|
||||
lobbyConfig.gameStartInfo.gameID,
|
||||
lobbyConfig.gameStartInfo.players,
|
||||
);
|
||||
|
||||
console.log("going to init path finder");
|
||||
|
||||
@@ -198,8 +198,8 @@ export class NameLayer implements Layer {
|
||||
element.style.aspectRatio = "3/4";
|
||||
};
|
||||
|
||||
if (player.flag()) {
|
||||
const flag = player.flag();
|
||||
if (player.cosmetics.flag) {
|
||||
const flag = player.cosmetics.flag;
|
||||
if (flag !== undefined && flag !== null && flag.startsWith("!")) {
|
||||
const flagWrapper = document.createElement("div");
|
||||
applyFlagStyles(flagWrapper);
|
||||
|
||||
@@ -207,21 +207,21 @@ export class PlayerInfoOverlay extends LitElement implements Layer {
|
||||
? "text-green-500"
|
||||
: "text-white"}"
|
||||
>
|
||||
${player.flag()
|
||||
? player.flag()!.startsWith("!")
|
||||
${player.cosmetics.flag
|
||||
? player.cosmetics.flag!.startsWith("!")
|
||||
? html`<div
|
||||
class="h-8 mr-1 aspect-[3/4] player-flag"
|
||||
${ref((el) => {
|
||||
if (el instanceof HTMLElement) {
|
||||
requestAnimationFrame(() => {
|
||||
renderPlayerFlag(player.flag()!, el);
|
||||
renderPlayerFlag(player.cosmetics.flag!, el);
|
||||
});
|
||||
}
|
||||
})}
|
||||
></div>`
|
||||
: html`<img
|
||||
class="h-8 mr-1 aspect-[3/4]"
|
||||
src=${"/flags/" + player.flag()! + ".svg"}
|
||||
src=${"/flags/" + player.cosmetics.flag! + ".svg"}
|
||||
/>`
|
||||
: html``}
|
||||
${player.name()}
|
||||
|
||||
@@ -307,7 +307,7 @@ export class TerritoryLayer implements Layer {
|
||||
this.paintTile(tile, useBorderColor, 255);
|
||||
}
|
||||
} else {
|
||||
const pattern = owner.pattern();
|
||||
const pattern = owner.cosmetics.pattern;
|
||||
const patternsEnabled = this.cachedTerritoryPatternsEnabled ?? false;
|
||||
if (pattern === undefined || patternsEnabled === false) {
|
||||
this.paintTile(tile, this.theme.territoryColor(owner), 150);
|
||||
|
||||
+1
-10
@@ -42,8 +42,6 @@ export async function createGameRunner(
|
||||
const humans = gameStart.players.map(
|
||||
(p) =>
|
||||
new PlayerInfo(
|
||||
p.pattern,
|
||||
p.flag,
|
||||
p.clientID === clientID
|
||||
? sanitize(p.username)
|
||||
: fixProfaneUsername(sanitize(p.username)),
|
||||
@@ -60,14 +58,7 @@ export async function createGameRunner(
|
||||
new Nation(
|
||||
new Cell(n.coordinates[0], n.coordinates[1]),
|
||||
n.strength,
|
||||
new PlayerInfo(
|
||||
undefined,
|
||||
n.flag || "",
|
||||
n.name,
|
||||
PlayerType.FakeHuman,
|
||||
null,
|
||||
random.nextID(),
|
||||
),
|
||||
new PlayerInfo(n.name, PlayerType.FakeHuman, null, random.nextID()),
|
||||
),
|
||||
);
|
||||
|
||||
|
||||
@@ -46,14 +46,7 @@ export class BotSpawner {
|
||||
}
|
||||
}
|
||||
return new SpawnExecution(
|
||||
new PlayerInfo(
|
||||
undefined,
|
||||
"",
|
||||
botName,
|
||||
PlayerType.Bot,
|
||||
null,
|
||||
this.random.nextID(),
|
||||
),
|
||||
new PlayerInfo(botName, PlayerType.Bot, null, this.random.nextID()),
|
||||
tile,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -350,8 +350,6 @@ export class PlayerInfo {
|
||||
public readonly clan: string | null;
|
||||
|
||||
constructor(
|
||||
public readonly pattern: string | undefined,
|
||||
public readonly flag: string | undefined,
|
||||
public readonly name: string,
|
||||
public readonly playerType: PlayerType,
|
||||
// null if bot.
|
||||
|
||||
@@ -133,8 +133,6 @@ export interface PlayerUpdate {
|
||||
type: GameUpdateType.Player;
|
||||
nameViewData?: NameViewData;
|
||||
clientID: ClientID | null;
|
||||
pattern: string | undefined;
|
||||
flag: string | undefined;
|
||||
name: string;
|
||||
displayName: string;
|
||||
id: PlayerID;
|
||||
|
||||
+43
-25
@@ -1,6 +1,6 @@
|
||||
import { Config } from "../configuration/Config";
|
||||
import { PatternDecoder } from "../PatternDecoder";
|
||||
import { ClientID, GameID } from "../Schemas";
|
||||
import { ClientID, GameID, Player } from "../Schemas";
|
||||
import { createRandomName } from "../Util";
|
||||
import { WorkerClient } from "../worker/WorkerClient";
|
||||
import {
|
||||
@@ -9,11 +9,9 @@ import {
|
||||
GameUpdates,
|
||||
Gold,
|
||||
NameViewData,
|
||||
Player,
|
||||
PlayerActions,
|
||||
PlayerBorderTiles,
|
||||
PlayerID,
|
||||
PlayerInfo,
|
||||
PlayerProfile,
|
||||
PlayerType,
|
||||
Team,
|
||||
@@ -32,12 +30,18 @@ import {
|
||||
PlayerUpdate,
|
||||
UnitUpdate,
|
||||
} from "./GameUpdates";
|
||||
import { TerrainMapData } from "./TerrainMapLoader";
|
||||
import { TerraNulliusImpl } from "./TerraNulliusImpl";
|
||||
import { UnitGrid } from "./UnitGrid";
|
||||
import { UserSettings } from "./UserSettings";
|
||||
|
||||
const userSettings: UserSettings = new UserSettings();
|
||||
|
||||
interface PlayerCosmetics {
|
||||
pattern?: string | undefined;
|
||||
flag?: string | undefined;
|
||||
}
|
||||
|
||||
export class UnitView {
|
||||
public _wasUpdated = true;
|
||||
public lastPos: TileRef[] = [];
|
||||
@@ -145,6 +149,7 @@ export class PlayerView {
|
||||
private game: GameView,
|
||||
public data: PlayerUpdate,
|
||||
public nameData: NameViewData,
|
||||
public cosmetics: PlayerCosmetics,
|
||||
) {
|
||||
if (data.clientID === game.myClientID()) {
|
||||
this.anonymousName = this.data.name;
|
||||
@@ -155,7 +160,9 @@ export class PlayerView {
|
||||
);
|
||||
}
|
||||
this.decoder =
|
||||
data.pattern === undefined ? undefined : new PatternDecoder(data.pattern);
|
||||
this.cosmetics.pattern === undefined
|
||||
? undefined
|
||||
: new PatternDecoder(this.cosmetics.pattern);
|
||||
}
|
||||
|
||||
patternDecoder(): PatternDecoder | undefined {
|
||||
@@ -202,13 +209,6 @@ export class PlayerView {
|
||||
smallID(): number {
|
||||
return this.data.smallID;
|
||||
}
|
||||
flag(): string | undefined {
|
||||
return this.data.flag;
|
||||
}
|
||||
|
||||
pattern(): string | undefined {
|
||||
return this.data.pattern;
|
||||
}
|
||||
|
||||
name(): string {
|
||||
return this.anonymousName !== null && userSettings.anonymousNames()
|
||||
@@ -236,7 +236,7 @@ export class PlayerView {
|
||||
isAlive(): boolean {
|
||||
return this.data.isAlive;
|
||||
}
|
||||
isPlayer(): this is Player {
|
||||
isPlayer(): this is PlayerView {
|
||||
return true;
|
||||
}
|
||||
numTilesOwned(): number {
|
||||
@@ -306,16 +306,7 @@ export class PlayerView {
|
||||
outgoingEmojis(): EmojiMessage[] {
|
||||
return this.data.outgoingEmojis;
|
||||
}
|
||||
info(): PlayerInfo {
|
||||
return new PlayerInfo(
|
||||
this.pattern(),
|
||||
this.flag(),
|
||||
this.name(),
|
||||
this.type(),
|
||||
this.clientID(),
|
||||
this.id(),
|
||||
);
|
||||
}
|
||||
|
||||
hasSpawned(): boolean {
|
||||
return this.data.hasSpawned;
|
||||
}
|
||||
@@ -338,16 +329,35 @@ export class GameView implements GameMap {
|
||||
|
||||
private toDelete = new Set<number>();
|
||||
|
||||
private _cosmetics: Map<string, PlayerCosmetics> = new Map();
|
||||
|
||||
private _map: GameMap;
|
||||
|
||||
constructor(
|
||||
public worker: WorkerClient,
|
||||
private _config: Config,
|
||||
private _map: GameMap,
|
||||
private _mapData: TerrainMapData,
|
||||
private _myClientID: ClientID,
|
||||
private _gameID: GameID,
|
||||
private _hunans: Player[],
|
||||
) {
|
||||
this._map = this._mapData.gameMap;
|
||||
this.lastUpdate = null;
|
||||
this.unitGrid = new UnitGrid(_map);
|
||||
this.unitGrid = new UnitGrid(this._map);
|
||||
this._cosmetics = new Map(
|
||||
this._hunans.map((h) => [
|
||||
h.clientID,
|
||||
{ flag: h.flag, pattern: h.pattern } satisfies PlayerCosmetics,
|
||||
]),
|
||||
);
|
||||
for (const nation of this._mapData.manifest.nations) {
|
||||
// Nations don't have client ids, so we use their name as the key instead.
|
||||
this._cosmetics.set(nation.name, {
|
||||
flag: nation.flag,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
isOnEdgeOfMap(ref: TileRef): boolean {
|
||||
return this._map.isOnEdgeOfMap(ref);
|
||||
}
|
||||
@@ -379,7 +389,15 @@ export class GameView implements GameMap {
|
||||
} else {
|
||||
this._players.set(
|
||||
pu.id,
|
||||
new PlayerView(this, pu, gu.playerNameViewData[pu.id]),
|
||||
new PlayerView(
|
||||
this,
|
||||
pu,
|
||||
gu.playerNameViewData[pu.id],
|
||||
// First check human by clientID, then check nation by name.
|
||||
this._cosmetics.get(pu.clientID ?? "") ??
|
||||
this._cosmetics.get(pu.name) ??
|
||||
{},
|
||||
),
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -128,8 +128,6 @@ export class PlayerImpl implements Player {
|
||||
return {
|
||||
type: GameUpdateType.Player,
|
||||
clientID: this.clientID(),
|
||||
pattern: this.pattern(),
|
||||
flag: this.flag(),
|
||||
name: this.name(),
|
||||
displayName: this.displayName(),
|
||||
id: this.id(),
|
||||
@@ -177,14 +175,6 @@ export class PlayerImpl implements Player {
|
||||
return this._smallID;
|
||||
}
|
||||
|
||||
pattern(): string | undefined {
|
||||
return this.playerInfo.pattern;
|
||||
}
|
||||
|
||||
flag(): string | undefined {
|
||||
return this.playerInfo.flag;
|
||||
}
|
||||
|
||||
name(): string {
|
||||
return this._name;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user