diff --git a/resources/cosmetics/cosmetic_pack/test/manifest.json b/resources/cosmetics/cosmetic_pack/test/manifest.json deleted file mode 100644 index 14fcdc56d..000000000 --- a/resources/cosmetics/cosmetic_pack/test/manifest.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "id": "test", - "name": "Test", - "assets": { - "structure": { - "img": { - "port": "structure/test.png", - "city": "structure/test.png", - "factory": "structure/test.png", - "missilesilo": "structure/test.png", - "defensepost": "structure/test.png", - "samlauncher": "structure/test.png" - } - }, - "sprites": { - "transportship": "sprites/test.png", - "warship": "sprites/test.png", - "sammissile": "sprites/test.png", - "atombomb": "sprites/test.png", - "hydrogenbomb": "sprites/test.png", - "tradeship": "sprites/test.png", - "mirv": "sprites/test.png", - "engine": "sprites/test.png", - "carriage": "sprites/test.png", - "loadedcarriage": "sprites/test.png" - }, - "audio": {} - } -} diff --git a/resources/cosmetics/cosmetic_pack/test/sprites/test.png b/resources/cosmetics/cosmetic_pack/test/sprites/test.png deleted file mode 100644 index 5bba75c4c..000000000 Binary files a/resources/cosmetics/cosmetic_pack/test/sprites/test.png and /dev/null differ diff --git a/resources/cosmetics/cosmetic_pack/test/structure/test.png b/resources/images/test/test.png similarity index 100% rename from resources/cosmetics/cosmetic_pack/test/structure/test.png rename to resources/images/test/test.png diff --git a/src/client/ClientGameRunner.ts b/src/client/ClientGameRunner.ts index 6d405af77..76d6e5996 100644 --- a/src/client/ClientGameRunner.ts +++ b/src/client/ClientGameRunner.ts @@ -53,7 +53,25 @@ export interface LobbyConfig { serverConfig: ServerConfig; pattern: PlayerPattern | undefined; flag: string; - pack: string | undefined; + + structurePort: string | undefined; + structureCity: string | undefined; + structureFactory: string | undefined; + structureMissilesilo: string | undefined; + structureDefensepost: string | undefined; + structureSamlauncher: string | undefined; + + spriteTransportship: string | undefined; + spriteWarship: string | undefined; + spriteSammissile: string | undefined; + spriteAtombomb: string | undefined; + spriteHydrogenbomb: string | undefined; + spriteTradeship: string | undefined; + spriteMirv: string | undefined; + spriteEngine: string | undefined; + spriteCarriage: string | undefined; + spriteLoadedcarriage: string | undefined; + playerName: string; clientID: ClientID; gameID: GameID; diff --git a/src/client/CosmeticPackLoader.ts b/src/client/CosmeticPackLoader.ts index 1ffdd3587..b1afef9c0 100644 --- a/src/client/CosmeticPackLoader.ts +++ b/src/client/CosmeticPackLoader.ts @@ -1,62 +1,22 @@ -import test from "../../resources/cosmetics/cosmetic_pack/test/manifest.json"; -import { - CosmeticManifest, - CosmeticManifestSchema, -} from "../core/CosmeticSchemas"; +export function fetchUrl( + packId: string | undefined, + type: string, +): string | undefined { + // TODO: Fetches the resource URL from the API server. -function parseCosmeticManifest(json: unknown): CosmeticManifest { - const res = CosmeticManifestSchema.safeParse(json); - if (!res.success) { - throw new Error(`Invalid CosmeticManifest: ${res.error.message}`); - } - return res.data; -} + // Request parameters: + // - packKey: identifier of the cosmetic pack + // - type: asset type (e.g., "structurePort", "structureCity") + // Response: + // - URL string pointing to the requested asset + + // Even if this approach changes, this function will be responsible for obtaining the URL by some method. -function fetchManifest(packId: string): CosmeticManifest | undefined { switch (packId) { case "base": return; case "test": - return parseCosmeticManifest(test) as CosmeticManifest; + return "/images/test/test.png"; // Example URL for testing } return; } - -export async function resolveCosmeticUrl( - packId: string | undefined, - key: string | undefined, - fallback: string, -): Promise { - if (packId === undefined || key === undefined) { - return fallback; - } - try { - const manifest = fetchManifest(packId); - if (!manifest) { - return fallback; - } - // Determine category and subKey from the first "/" only. - const firstSlash = key.indexOf("/"); - if (firstSlash === -1) { - return fallback; - } - const category = key.slice(0, firstSlash); - const subKey = key.slice(firstSlash + 1); - - const table = (manifest.assets as Record)[category]; - if (table) { - const parts = subKey.split("/"); - let current: any = table; - for (const part of parts) { - if (current === null) break; - current = current[part]; - } - if (typeof current === "string") { - return `/cosmetics/cosmetic_pack/${packId}/${current}`; - } - } - } catch (e) { - console.warn("[cosmetics] manifest load failed", e); - } - return fallback; -} diff --git a/src/client/Main.ts b/src/client/Main.ts index 42cda33d3..b4f2d08c4 100644 --- a/src/client/Main.ts +++ b/src/client/Main.ts @@ -516,7 +516,37 @@ class Client { this.flagInput === null || this.flagInput.getCurrentFlag() === "xx" ? "" : this.flagInput.getCurrentFlag(), - pack: this.userSettings.getSelectedPackId() ?? undefined, + structurePort: + this.userSettings.getSelectedStructurePort() ?? undefined, + structureCity: + this.userSettings.getSelectedStructureCity() ?? undefined, + structureFactory: + this.userSettings.getSelectedStructureFactory() ?? undefined, + structureMissilesilo: + this.userSettings.getSelectedStructureMissilesilo() ?? undefined, + structureDefensepost: + this.userSettings.getSelectedStructureDefensepost() ?? undefined, + structureSamlauncher: + this.userSettings.getSelectedStructureSamlauncher() ?? undefined, + + spriteTransportship: + this.userSettings.getSelectedSpriteTransportship() ?? undefined, + spriteWarship: + this.userSettings.getSelectedSpriteWarship() ?? undefined, + spriteSammissile: + this.userSettings.getSelectedSpriteSammissile() ?? undefined, + spriteAtombomb: + this.userSettings.getSelectedSpriteAtombomb() ?? undefined, + spriteHydrogenbomb: + this.userSettings.getSelectedSpriteHydrogenbomb() ?? undefined, + spriteTradeship: + this.userSettings.getSelectedSpriteTradeship() ?? undefined, + spriteMirv: this.userSettings.getSelectedSpriteMirv() ?? undefined, + spriteEngine: this.userSettings.getSelectedSpriteEngine() ?? undefined, + spriteCarriage: + this.userSettings.getSelectedSpriteCarriage() ?? undefined, + spriteLoadedcarriage: + this.userSettings.getSelectedSpriteLoadedcarriage() ?? undefined, playerName: this.usernameInput?.getCurrentUsername() ?? "", token: getPlayToken(), clientID: lobby.clientID, diff --git a/src/client/SinglePlayerModal.ts b/src/client/SinglePlayerModal.ts index 1f1ef1582..48881c404 100644 --- a/src/client/SinglePlayerModal.ts +++ b/src/client/SinglePlayerModal.ts @@ -21,6 +21,7 @@ import "./components/baseComponents/Button"; import "./components/baseComponents/Modal"; import "./components/Difficulties"; import "./components/Maps"; +import { fetchUrl } from "./CosmeticPackLoader"; import { fetchCosmetics } from "./Cosmetics"; import { FlagInput } from "./FlagInput"; import { JoinLobbyEvent } from "./Main"; @@ -448,7 +449,6 @@ export class SinglePlayerModal extends LitElement { selectedPattern ??= cosmetics ? (this.userSettings.getDevOnlyPattern() ?? null) : null; - const selectedPackId = this.userSettings.getSelectedPackId(); this.dispatchEvent( new CustomEvent("join-lobby", { @@ -467,7 +467,84 @@ export class SinglePlayerModal extends LitElement { ? "" : flagInput.getCurrentFlag(), pattern: selectedPattern ?? undefined, - pack: selectedPackId ?? undefined, + pack: { + structurePort: fetchUrl( + this.userSettings.getSelectedStructurePort() ?? undefined, + "structurePort", + ), + structureCity: fetchUrl( + this.userSettings.getSelectedStructureCity() ?? undefined, + "structureCity", + ), + structureFactory: fetchUrl( + this.userSettings.getSelectedStructureFactory() ?? + undefined, + "structureFactory", + ), + structureMissilesilo: fetchUrl( + this.userSettings.getSelectedStructureMissilesilo() ?? + undefined, + "structureMissilesilo", + ), + structureDefensepost: fetchUrl( + this.userSettings.getSelectedStructureDefensepost() ?? + undefined, + "structureDefensepost", + ), + structureSamlauncher: fetchUrl( + this.userSettings.getSelectedStructureSamlauncher() ?? + undefined, + "structureSamlauncher", + ), + + spriteTransportship: fetchUrl( + this.userSettings.getSelectedSpriteTransportship() ?? + undefined, + "spriteTransportship", + ), + spriteWarship: fetchUrl( + this.userSettings.getSelectedSpriteWarship() ?? undefined, + "spriteWarship", + ), + spriteSammissile: fetchUrl( + this.userSettings.getSelectedSpriteSammissile() ?? + undefined, + "spriteSammissile", + ), + spriteAtombomb: fetchUrl( + this.userSettings.getSelectedSpriteAtombomb() ?? + undefined, + "spriteAtombomb", + ), + spriteHydrogenbomb: fetchUrl( + this.userSettings.getSelectedSpriteHydrogenbomb() ?? + undefined, + "spriteHydrogenbomb", + ), + spriteTradeship: fetchUrl( + this.userSettings.getSelectedSpriteTradeship() ?? + undefined, + "spriteTradeship", + ), + spriteMirv: fetchUrl( + this.userSettings.getSelectedSpriteMirv() ?? undefined, + "spriteMirv", + ), + spriteEngine: fetchUrl( + this.userSettings.getSelectedSpriteEngine() ?? undefined, + "spriteEngine", + ), + spriteCarriage: fetchUrl( + this.userSettings.getSelectedSpriteCarriage() ?? + undefined, + "spriteCarriage", + ), + spriteLoadedcarriage: fetchUrl( + this.userSettings.getSelectedSpriteLoadedcarriage() ?? + undefined, + "spriteLoadedcarriage", + ), + }, }, }, ], diff --git a/src/client/Transport.ts b/src/client/Transport.ts index 70755adaf..c5247c85a 100644 --- a/src/client/Transport.ts +++ b/src/client/Transport.ts @@ -381,7 +381,24 @@ export class Transport { flag: this.lobbyConfig.flag, patternName: this.lobbyConfig.pattern?.name, patternColorPaletteName: this.lobbyConfig.pattern?.colorPalette?.name, - pack: this.lobbyConfig.pack, + + structurePort: this.lobbyConfig.structurePort, + structureCity: this.lobbyConfig.structureCity, + structureFactory: this.lobbyConfig.structureFactory, + structureMissilesilo: this.lobbyConfig.structureMissilesilo, + structureDefensepost: this.lobbyConfig.structureDefensepost, + structureSamlauncher: this.lobbyConfig.structureSamlauncher, + + spriteTransportship: this.lobbyConfig.spriteTransportship, + spriteWarship: this.lobbyConfig.spriteWarship, + spriteSammissile: this.lobbyConfig.spriteSammissile, + spriteAtombomb: this.lobbyConfig.spriteAtombomb, + spriteHydrogenbomb: this.lobbyConfig.spriteHydrogenbomb, + spriteTradeship: this.lobbyConfig.spriteTradeship, + spriteMirv: this.lobbyConfig.spriteMirv, + spriteEngine: this.lobbyConfig.spriteEngine, + spriteCarriage: this.lobbyConfig.spriteCarriage, + spriteLoadedcarriage: this.lobbyConfig.spriteLoadedcarriage, }, } satisfies ClientJoinMessage); } diff --git a/src/client/graphics/SpriteLoader.ts b/src/client/graphics/SpriteLoader.ts index 7b411ec85..aa3b438e9 100644 --- a/src/client/graphics/SpriteLoader.ts +++ b/src/client/graphics/SpriteLoader.ts @@ -12,7 +12,7 @@ import warshipSprite from "../../../resources/sprites/warship.png"; import { Theme } from "../../core/configuration/Config"; import { TrainType, UnitType } from "../../core/game/Game"; import { UnitView } from "../../core/game/GameView"; -import { resolveCosmeticUrl } from "../CosmeticPackLoader"; +import { PlayerPack } from "../../core/Schemas"; // Can't reuse TrainType because "loaded" is not a type, just an attribute const TrainTypeSprite = { @@ -27,25 +27,25 @@ const SPRITE_CONFIG: Partial< Record > = { [UnitType.TransportShip]: { - key: "sprites/transportship", + key: "spriteTransportship", url: transportShipSprite, }, - [UnitType.Warship]: { key: "sprites/warship", url: warshipSprite }, - [UnitType.SAMMissile]: { key: "sprites/sammissile", url: samMissileSprite }, - [UnitType.AtomBomb]: { key: "sprites/atombomb", url: atomBombSprite }, + [UnitType.Warship]: { key: "spriteWarship", url: warshipSprite }, + [UnitType.SAMMissile]: { key: "spriteSammissile", url: samMissileSprite }, + [UnitType.AtomBomb]: { key: "spriteAtombomb", url: atomBombSprite }, [UnitType.HydrogenBomb]: { - key: "sprites/hydrogenbomb", + key: "spriteHydrogenbomb", url: hydrogenBombSprite, }, - [UnitType.TradeShip]: { key: "sprites/tradeship", url: tradeShipSprite }, - [UnitType.MIRV]: { key: "sprites/mirv", url: mirvSprite }, - [TrainTypeSprite.Engine]: { key: "sprites/engine", url: trainEngineSprite }, + [UnitType.TradeShip]: { key: "spriteTradeship", url: tradeShipSprite }, + [UnitType.MIRV]: { key: "spriteMirv", url: mirvSprite }, + [TrainTypeSprite.Engine]: { key: "spriteEngine", url: trainEngineSprite }, [TrainTypeSprite.Carriage]: { - key: "sprites/carriage", + key: "spriteCarriage", url: trainCarriageSprite, }, [TrainTypeSprite.LoadedCarriage]: { - key: "sprites/loadedcarriage", + key: "spriteLoadedcarriage", url: trainLoadedCarriageSprite, }, }; @@ -53,9 +53,7 @@ const SPRITE_CONFIG: Partial< const spriteMap: Map = new Map(); // preload all images -export const loadAllSprites = async ( - packId: string | undefined, -): Promise => { +export const loadAllSprites = async (pack: PlayerPack): Promise => { const entries = Object.entries(SPRITE_CONFIG); const totalSprites = entries.length; let loadedCount = 0; @@ -71,7 +69,8 @@ export const loadAllSprites = async ( console.warn(`No sprite url for ${typedUnitType}, skipping...`); return; } - const url = await resolveCosmeticUrl(packId, key, fallbackUrl); + + const url = pack?.[key] ?? fallbackUrl; try { const img = new Image(); diff --git a/src/client/graphics/layers/StructureLayer.ts b/src/client/graphics/layers/StructureLayer.ts index 2c900bfdb..6a5430666 100644 --- a/src/client/graphics/layers/StructureLayer.ts +++ b/src/client/graphics/layers/StructureLayer.ts @@ -11,7 +11,7 @@ import { Cell, UnitType } from "../../../core/game/Game"; import { euclDistFN, isometricDistFN } from "../../../core/game/GameMap"; import { GameUpdateType } from "../../../core/game/GameUpdates"; import { GameView, UnitView } from "../../../core/game/GameView"; -import { resolveCosmeticUrl } from "../../CosmeticPackLoader"; +import { PlayerPack } from "../../../core/Schemas"; import { TransformHandler } from "../TransformHandler"; import { Layer } from "./Layer"; @@ -25,6 +25,7 @@ const ZOOM_THRESHOLD = 4.3; // below this zoom level, structures are not rendere interface UnitRenderConfig { icon: string; + key: string; borderRadius: number; territoryRadius: number; } @@ -34,7 +35,7 @@ export class StructureLayer implements Layer { private context: CanvasRenderingContext2D; private unitIcons: Map = new Map(); private theme: Theme; - private packId: string | undefined; + private pack: PlayerPack; private structureLoaded = false; private tempCanvas: HTMLCanvasElement; private tempContext: CanvasRenderingContext2D; @@ -43,31 +44,37 @@ export class StructureLayer implements Layer { private unitConfigs: Partial> = { [UnitType.Port]: { icon: anchorIcon, + key: "structurePort", borderRadius: BASE_BORDER_RADIUS * RADIUS_SCALE_FACTOR, territoryRadius: BASE_TERRITORY_RADIUS * RADIUS_SCALE_FACTOR, }, [UnitType.City]: { icon: cityIcon, + key: "structureCity", borderRadius: BASE_BORDER_RADIUS * RADIUS_SCALE_FACTOR, territoryRadius: BASE_TERRITORY_RADIUS * RADIUS_SCALE_FACTOR, }, [UnitType.Factory]: { icon: factoryIcon, + key: "structureFactory", borderRadius: BASE_BORDER_RADIUS * RADIUS_SCALE_FACTOR, territoryRadius: BASE_TERRITORY_RADIUS * RADIUS_SCALE_FACTOR, }, [UnitType.MissileSilo]: { icon: missileSiloIcon, + key: "structureMissilesilo", borderRadius: BASE_BORDER_RADIUS * RADIUS_SCALE_FACTOR, territoryRadius: BASE_TERRITORY_RADIUS * RADIUS_SCALE_FACTOR, }, [UnitType.DefensePost]: { icon: shieldIcon, + key: "structureDefensepost", borderRadius: BASE_BORDER_RADIUS * RADIUS_SCALE_FACTOR, territoryRadius: BASE_TERRITORY_RADIUS * RADIUS_SCALE_FACTOR, }, [UnitType.SAMLauncher]: { icon: SAMMissileIcon, + key: "structureSamlauncher", borderRadius: BASE_BORDER_RADIUS * RADIUS_SCALE_FACTOR, territoryRadius: BASE_TERRITORY_RADIUS * RADIUS_SCALE_FACTOR, }, @@ -88,6 +95,7 @@ export class StructureLayer implements Layer { private loadIcon(unitType: string, config: UnitRenderConfig) { const image = new Image(); + console.log(`loading icon for ${unitType} from ${config.icon}`); image.src = config.icon; image.onload = () => { this.unitIcons.set(unitType, image); @@ -101,8 +109,8 @@ export class StructureLayer implements Layer { } private async loadIconData() { - await this.applyCosmeticIcons(); Object.entries(this.unitConfigs).forEach(([unitType, config]) => { + config.icon = this.pack?.[config.key] ?? config.icon; this.loadIcon(unitType, config); }); } @@ -122,7 +130,7 @@ export class StructureLayer implements Layer { if (!this.structureLoaded) { const myPlayer = this.game.myPlayer(); if (myPlayer) { - this.packId = myPlayer.cosmetics.pack; + this.pack = myPlayer.cosmetics.pack ?? {}; this.loadIconData(); this.structureLoaded = true; } @@ -133,57 +141,6 @@ export class StructureLayer implements Layer { this.redraw(); } - private async applyCosmeticIcons(): Promise { - this.unitConfigs[UnitType.Port] = { - ...this.unitConfigs[UnitType.Port]!, - icon: await resolveCosmeticUrl( - this.packId, - "structure/img/port", - anchorIcon, - ), - }; - this.unitConfigs[UnitType.City] = { - ...this.unitConfigs[UnitType.City]!, - icon: await resolveCosmeticUrl( - this.packId, - "structure/img/city", - cityIcon, - ), - }; - this.unitConfigs[UnitType.Factory] = { - ...this.unitConfigs[UnitType.Factory]!, - icon: await resolveCosmeticUrl( - this.packId, - "structure/img/factory", - factoryIcon, - ), - }; - this.unitConfigs[UnitType.MissileSilo] = { - ...this.unitConfigs[UnitType.MissileSilo]!, - icon: await resolveCosmeticUrl( - this.packId, - "structure/img/missilesilo", - missileSiloIcon, - ), - }; - this.unitConfigs[UnitType.DefensePost] = { - ...this.unitConfigs[UnitType.DefensePost]!, - icon: await resolveCosmeticUrl( - this.packId, - "structure/img/defensepost", - shieldIcon, - ), - }; - this.unitConfigs[UnitType.SAMLauncher] = { - ...this.unitConfigs[UnitType.SAMLauncher]!, - icon: await resolveCosmeticUrl( - this.packId, - "structure/img/samlauncher", - SAMMissileIcon, - ), - }; - } - redraw() { console.log("structure layer redrawing"); this.canvas = document.createElement("canvas"); diff --git a/src/client/graphics/layers/UnitLayer.ts b/src/client/graphics/layers/UnitLayer.ts index a0a510518..90c7faacf 100644 --- a/src/client/graphics/layers/UnitLayer.ts +++ b/src/client/graphics/layers/UnitLayer.ts @@ -14,6 +14,7 @@ import { MoveWarshipIntentEvent } from "../../Transport"; import { TransformHandler } from "../TransformHandler"; import { Layer } from "./Layer"; +import { PlayerPack } from "../../../core/Schemas"; import { GameUpdateType } from "../../../core/game/GameUpdates"; import { getColoredSprite, @@ -36,7 +37,7 @@ export class UnitLayer implements Layer { private unitToTrail = new Map(); private theme: Theme; - private packId: string | undefined = undefined; + private pack: PlayerPack; private spritesLoaded = false; private alternateView = false; @@ -74,8 +75,8 @@ export class UnitLayer implements Layer { if (!this.spritesLoaded) { const myPlayer = this.game.myPlayer(); if (myPlayer) { - this.packId = myPlayer.cosmetics.pack; - loadAllSprites(this.packId); + this.pack = myPlayer.cosmetics.pack ?? {}; + loadAllSprites(this.pack); this.spritesLoaded = true; } } @@ -86,7 +87,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(this.packId); + loadAllSprites(this.pack); } /** diff --git a/src/core/Schemas.ts b/src/core/Schemas.ts index 5c54dc556..210322b6a 100644 --- a/src/core/Schemas.ts +++ b/src/core/Schemas.ts @@ -390,7 +390,24 @@ export const PlayerCosmeticRefsSchema = z.object({ flag: FlagSchema.optional(), patternName: PatternNameSchema.optional(), patternColorPaletteName: z.string().optional(), - pack: z.string().optional(), + + structurePort: z.string().optional(), + structureCity: z.string().optional(), + structureFactory: z.string().optional(), + structureMissilesilo: z.string().optional(), + structureDefensepost: z.string().optional(), + structureSamlauncher: z.string().optional(), + + spriteTransportship: z.string().optional(), + spriteWarship: z.string().optional(), + spriteSammissile: z.string().optional(), + spriteAtombomb: z.string().optional(), + spriteHydrogenbomb: z.string().optional(), + spriteTradeship: z.string().optional(), + spriteMirv: z.string().optional(), + spriteEngine: z.string().optional(), + spriteCarriage: z.string().optional(), + spriteLoadedcarriage: z.string().optional(), }); export const PlayerPatternSchema = z.object({ @@ -398,10 +415,32 @@ export const PlayerPatternSchema = z.object({ patternData: PatternDataSchema, colorPalette: ColorPaletteSchema.optional(), }); + +export const PlayerPackSchema = z.object({ + structurePort: z.string().optional(), + structureCity: z.string().optional(), + structureFactory: z.string().optional(), + structureMissilesilo: z.string().optional(), + structureDefensepost: z.string().optional(), + structureSamlauncher: z.string().optional(), + + spriteTransportship: z.string().optional(), + spriteWarship: z.string().optional(), + spriteSammissile: z.string().optional(), + spriteAtombomb: z.string().optional(), + spriteHydrogenbomb: z.string().optional(), + spriteTradeship: z.string().optional(), + spriteMirv: z.string().optional(), + spriteEngine: z.string().optional(), + spriteCarriage: z.string().optional(), + spriteLoadedcarriage: z.string().optional(), +}); +export type PlayerPack = z.infer; + export const PlayerCosmeticsSchema = z.object({ flag: FlagSchema.optional(), pattern: PlayerPatternSchema.optional(), - pack: z.string().optional(), + pack: PlayerPackSchema.optional(), }); export const PlayerSchema = z.object({ clientID: ID, diff --git a/src/core/game/UserSettings.ts b/src/core/game/UserSettings.ts index 9392703eb..1635e5c18 100644 --- a/src/core/game/UserSettings.ts +++ b/src/core/game/UserSettings.ts @@ -169,8 +169,68 @@ export class UserSettings { } } - getSelectedPackId(): string | undefined { - return localStorage.getItem("cosmeticPackId") ?? undefined; + getSelectedStructurePort(): string | undefined { + return localStorage.getItem("structurePort") ?? undefined; + } + + getSelectedStructureCity(): string | undefined { + return localStorage.getItem("structureCity") ?? undefined; + } + + getSelectedStructureFactory(): string | undefined { + return localStorage.getItem("structureFactory") ?? undefined; + } + + getSelectedStructureMissilesilo(): string | undefined { + return localStorage.getItem("structureMissilesilo") ?? undefined; + } + + getSelectedStructureDefensepost(): string | undefined { + return localStorage.getItem("structureDefensepost") ?? undefined; + } + + getSelectedStructureSamlauncher(): string | undefined { + return localStorage.getItem("structureSamlauncher") ?? undefined; + } + + getSelectedSpriteTransportship(): string | undefined { + return localStorage.getItem("spriteTransportship") ?? undefined; + } + + getSelectedSpriteWarship(): string | undefined { + return localStorage.getItem("spriteWarship") ?? undefined; + } + + getSelectedSpriteSammissile(): string | undefined { + return localStorage.getItem("spriteSammissile") ?? undefined; + } + + getSelectedSpriteAtombomb(): string | undefined { + return localStorage.getItem("spriteAtombomb") ?? undefined; + } + + getSelectedSpriteHydrogenbomb(): string | undefined { + return localStorage.getItem("spriteHydrogenbomb") ?? undefined; + } + + getSelectedSpriteTradeship(): string | undefined { + return localStorage.getItem("spriteTradeship") ?? undefined; + } + + getSelectedSpriteMirv(): string | undefined { + return localStorage.getItem("spriteMirv") ?? undefined; + } + + getSelectedSpriteEngine(): string | undefined { + return localStorage.getItem("spriteEngine") ?? undefined; + } + + getSelectedSpriteCarriage(): string | undefined { + return localStorage.getItem("spriteCarriage") ?? undefined; + } + + getSelectedSpriteLoadedcarriage(): string | undefined { + return localStorage.getItem("spriteLoadedcarriage") ?? undefined; } backgroundMusicVolume(): number { diff --git a/src/server/Worker.ts b/src/server/Worker.ts index 9e1d48274..a619119c9 100644 --- a/src/server/Worker.ts +++ b/src/server/Worker.ts @@ -7,6 +7,7 @@ import path from "path"; import { fileURLToPath } from "url"; import { WebSocket, WebSocketServer } from "ws"; import { z } from "zod"; +import { fetchUrl } from "../client/CosmeticPackLoader"; import { getServerConfigFromServer } from "../core/configuration/ConfigLoader"; import { GameType } from "../core/game/Game"; import { @@ -485,12 +486,56 @@ export async function startWorker() { } } + // Temporary full assignment (unless there’s a better approach). + const pack = { + structurePort: fetchUrl(cosmetics.structurePort, "structurePort"), + structureCity: fetchUrl(cosmetics.structureCity, "structureCity"), + structureFactory: fetchUrl( + cosmetics.structureFactory, + "structureFactory", + ), + structureMissilesilo: fetchUrl( + cosmetics.structureMissilesilo, + "structureMissilesilo", + ), + structureDefensepost: fetchUrl( + cosmetics.structureDefensepost, + "structureDefensepost", + ), + structureSamlauncher: fetchUrl( + cosmetics.structureSamlauncher, + "structureSamlauncher", + ), + spriteTransportship: fetchUrl( + cosmetics.spriteTransportship, + "spriteTransportship", + ), + spriteWarship: fetchUrl(cosmetics.spriteWarship, "spriteWarship"), + spriteSammissile: fetchUrl( + cosmetics.spriteSammissile, + "spriteSammissile", + ), + spriteAtombomb: fetchUrl(cosmetics.spriteAtombomb, "spriteAtombomb"), + spriteHydrogenbomb: fetchUrl( + cosmetics.spriteHydrogenbomb, + "spriteHydrogenbomb", + ), + spriteTradeship: fetchUrl(cosmetics.spriteTradeship, "spriteTradeship"), + spriteMirv: fetchUrl(cosmetics.spriteMirv, "spriteMirv"), + spriteEngine: fetchUrl(cosmetics.spriteEngine, "spriteEngine"), + spriteCarriage: fetchUrl(cosmetics.spriteCarriage, "spriteCarriage"), + spriteLoadedcarriage: fetchUrl( + cosmetics.spriteLoadedcarriage, + "spriteLoadedcarriage", + ), + }; + return { perm: "allowed", cosmetics: { flag: cosmetics.flag, pattern: pattern, - pack: cosmetics.pack, + pack: pack, }, }; }