mirror of
https://github.com/openfrontio/OpenFrontIO.git
synced 2026-06-23 11:58:08 +00:00
Add pack handling to lobby configuration and cosmetic loading
This commit is contained in:
@@ -52,6 +52,7 @@ export interface LobbyConfig {
|
||||
serverConfig: ServerConfig;
|
||||
pattern: PlayerPattern | undefined;
|
||||
flag: string;
|
||||
pack: string | undefined;
|
||||
playerName: string;
|
||||
clientID: ClientID;
|
||||
gameID: GameID;
|
||||
|
||||
@@ -23,11 +23,11 @@ function fetchManifest(packId: string): CosmeticManifest | undefined {
|
||||
}
|
||||
|
||||
export async function resolveCosmeticUrl(
|
||||
packId: string | null,
|
||||
packId: string | undefined,
|
||||
key: string | undefined,
|
||||
fallback: string,
|
||||
): Promise<string> {
|
||||
if (!packId || key === undefined) {
|
||||
if (packId === undefined || key === undefined) {
|
||||
return fallback;
|
||||
}
|
||||
try {
|
||||
|
||||
@@ -516,6 +516,7 @@ class Client {
|
||||
this.flagInput === null || this.flagInput.getCurrentFlag() === "xx"
|
||||
? ""
|
||||
: this.flagInput.getCurrentFlag(),
|
||||
pack: this.userSettings.getSelectedPackId() ?? undefined,
|
||||
playerName: this.usernameInput?.getCurrentUsername() ?? "",
|
||||
token: getPlayToken(),
|
||||
clientID: lobby.clientID,
|
||||
|
||||
@@ -448,6 +448,7 @@ export class SinglePlayerModal extends LitElement {
|
||||
selectedPattern ??= cosmetics
|
||||
? (this.userSettings.getDevOnlyPattern() ?? null)
|
||||
: null;
|
||||
const selectedPackId = this.userSettings.getSelectedPackId();
|
||||
|
||||
this.dispatchEvent(
|
||||
new CustomEvent("join-lobby", {
|
||||
@@ -466,6 +467,7 @@ export class SinglePlayerModal extends LitElement {
|
||||
? ""
|
||||
: flagInput.getCurrentFlag(),
|
||||
pattern: selectedPattern ?? undefined,
|
||||
pack: selectedPackId ?? undefined,
|
||||
},
|
||||
},
|
||||
],
|
||||
|
||||
@@ -381,6 +381,7 @@ export class Transport {
|
||||
flag: this.lobbyConfig.flag,
|
||||
patternName: this.lobbyConfig.pattern?.name,
|
||||
patternColorPaletteName: this.lobbyConfig.pattern?.colorPalette?.name,
|
||||
pack: this.lobbyConfig.pack,
|
||||
},
|
||||
} satisfies ClientJoinMessage);
|
||||
}
|
||||
|
||||
@@ -53,13 +53,13 @@ const SPRITE_CONFIG: Partial<
|
||||
const spriteMap: Map<UnitType | TrainTypeSprite, ImageBitmap> = new Map();
|
||||
|
||||
// preload all images
|
||||
export const loadAllSprites = async (): Promise<void> => {
|
||||
export const loadAllSprites = async (
|
||||
packId: string | undefined,
|
||||
): Promise<void> => {
|
||||
const entries = Object.entries(SPRITE_CONFIG);
|
||||
const totalSprites = entries.length;
|
||||
let loadedCount = 0;
|
||||
|
||||
const packId: string | null = "test"; // TODO: wire from server/client selection
|
||||
|
||||
await Promise.all(
|
||||
entries.map(async ([unitType, value]) => {
|
||||
const typedUnitType = unitType as UnitType | TrainTypeSprite;
|
||||
|
||||
@@ -34,6 +34,8 @@ export class StructureLayer implements Layer {
|
||||
private context: CanvasRenderingContext2D;
|
||||
private unitIcons: Map<string, HTMLImageElement> = new Map();
|
||||
private theme: Theme;
|
||||
private packId: string | undefined;
|
||||
private structureLoaded = false;
|
||||
private tempCanvas: HTMLCanvasElement;
|
||||
private tempContext: CanvasRenderingContext2D;
|
||||
|
||||
@@ -117,6 +119,14 @@ export class StructureLayer implements Layer {
|
||||
if (unit === undefined) continue;
|
||||
this.handleUnitRendering(unit);
|
||||
}
|
||||
if (!this.structureLoaded) {
|
||||
const myPlayer = this.game.myPlayer();
|
||||
if (myPlayer) {
|
||||
this.packId = myPlayer.cosmetics.pack;
|
||||
this.loadIconData();
|
||||
this.structureLoaded = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
init() {
|
||||
@@ -124,23 +134,26 @@ export class StructureLayer implements Layer {
|
||||
}
|
||||
|
||||
private async applyCosmeticIcons(): Promise<void> {
|
||||
const packSpec = "test";
|
||||
this.unitConfigs[UnitType.Port] = {
|
||||
...this.unitConfigs[UnitType.Port]!,
|
||||
icon: await resolveCosmeticUrl(
|
||||
packSpec,
|
||||
this.packId,
|
||||
"structure/img/port",
|
||||
anchorIcon,
|
||||
),
|
||||
};
|
||||
this.unitConfigs[UnitType.City] = {
|
||||
...this.unitConfigs[UnitType.City]!,
|
||||
icon: await resolveCosmeticUrl(packSpec, "structure/img/city", cityIcon),
|
||||
icon: await resolveCosmeticUrl(
|
||||
this.packId,
|
||||
"structure/img/city",
|
||||
cityIcon,
|
||||
),
|
||||
};
|
||||
this.unitConfigs[UnitType.Factory] = {
|
||||
...this.unitConfigs[UnitType.Factory]!,
|
||||
icon: await resolveCosmeticUrl(
|
||||
packSpec,
|
||||
this.packId,
|
||||
"structure/img/factory",
|
||||
factoryIcon,
|
||||
),
|
||||
@@ -148,7 +161,7 @@ export class StructureLayer implements Layer {
|
||||
this.unitConfigs[UnitType.MissileSilo] = {
|
||||
...this.unitConfigs[UnitType.MissileSilo]!,
|
||||
icon: await resolveCosmeticUrl(
|
||||
packSpec,
|
||||
this.packId,
|
||||
"structure/img/missilesilo",
|
||||
missileSiloIcon,
|
||||
),
|
||||
@@ -156,7 +169,7 @@ export class StructureLayer implements Layer {
|
||||
this.unitConfigs[UnitType.DefensePost] = {
|
||||
...this.unitConfigs[UnitType.DefensePost]!,
|
||||
icon: await resolveCosmeticUrl(
|
||||
packSpec,
|
||||
this.packId,
|
||||
"structure/img/defensepost",
|
||||
shieldIcon,
|
||||
),
|
||||
@@ -164,7 +177,7 @@ export class StructureLayer implements Layer {
|
||||
this.unitConfigs[UnitType.SAMLauncher] = {
|
||||
...this.unitConfigs[UnitType.SAMLauncher]!,
|
||||
icon: await resolveCosmeticUrl(
|
||||
packSpec,
|
||||
this.packId,
|
||||
"structure/img/samlauncher",
|
||||
SAMMissileIcon,
|
||||
),
|
||||
|
||||
@@ -36,6 +36,8 @@ export class UnitLayer implements Layer {
|
||||
private unitToTrail = new Map<UnitView, TileRef[]>();
|
||||
|
||||
private theme: Theme;
|
||||
private packId: string | undefined = undefined;
|
||||
private spritesLoaded = false;
|
||||
|
||||
private alternateView = false;
|
||||
|
||||
@@ -68,6 +70,15 @@ export class UnitLayer implements Layer {
|
||||
?.[GameUpdateType.Unit]?.map((unit) => unit.id);
|
||||
|
||||
this.updateUnitsSprites(unitIds ?? []);
|
||||
|
||||
if (!this.spritesLoaded) {
|
||||
const myPlayer = this.game.myPlayer();
|
||||
if (myPlayer) {
|
||||
this.packId = myPlayer.cosmetics.pack;
|
||||
loadAllSprites(this.packId);
|
||||
this.spritesLoaded = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
init() {
|
||||
@@ -75,8 +86,7 @@ export class UnitLayer implements Layer {
|
||||
this.eventBus.on(MouseUpEvent, (e) => this.onMouseUp(e));
|
||||
this.eventBus.on(UnitSelectionEvent, (e) => this.onUnitSelectionChange(e));
|
||||
this.redraw();
|
||||
|
||||
loadAllSprites();
|
||||
loadAllSprites(this.packId);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -390,6 +390,7 @@ export const PlayerCosmeticRefsSchema = z.object({
|
||||
flag: FlagSchema.optional(),
|
||||
patternName: PatternNameSchema.optional(),
|
||||
patternColorPaletteName: z.string().optional(),
|
||||
pack: z.string().optional(),
|
||||
});
|
||||
|
||||
export const PlayerPatternSchema = z.object({
|
||||
@@ -400,6 +401,7 @@ export const PlayerPatternSchema = z.object({
|
||||
export const PlayerCosmeticsSchema = z.object({
|
||||
flag: FlagSchema.optional(),
|
||||
pattern: PlayerPatternSchema.optional(),
|
||||
pack: z.string().optional(),
|
||||
});
|
||||
export const PlayerSchema = z.object({
|
||||
clientID: ID,
|
||||
|
||||
@@ -154,4 +154,8 @@ export class UserSettings {
|
||||
localStorage.setItem(PATTERN_KEY, patternName);
|
||||
}
|
||||
}
|
||||
|
||||
getSelectedPackId(): string | undefined {
|
||||
return localStorage.getItem("cosmeticPackId") ?? undefined;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -490,6 +490,7 @@ export async function startWorker() {
|
||||
cosmetics: {
|
||||
flag: cosmetics.flag,
|
||||
pattern: pattern,
|
||||
pack: cosmetics.pack,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user