From c56eaa258d84548d543a504c525d3229edfad05e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tr=C3=A8sAbhi?= <43380238+tresabhi@users.noreply.github.com> Date: Wed, 17 Jan 2024 11:34:27 -0600 Subject: [PATCH] feat: consumable icons --- scripts/buildAssets/constants.ts | 5 +- scripts/buildAssets/consumableIcons.ts | 149 +++++++++++++++++++++++++ scripts/buildAssets/definitions.ts | 6 +- scripts/buildAssets/index.ts | 5 + 4 files changed, 161 insertions(+), 4 deletions(-) create mode 100644 scripts/buildAssets/consumableIcons.ts diff --git a/scripts/buildAssets/constants.ts b/scripts/buildAssets/constants.ts index 64d41be23..da9183931 100644 --- a/scripts/buildAssets/constants.ts +++ b/scripts/buildAssets/constants.ts @@ -19,5 +19,8 @@ export const POI = { 'UI/Screens3/Lobby/Inventory/OptionalDevices/OptionalDevicesItemImage.style.yaml', optionalDevicesImage: 'Gfx/UI/InventoryIcons/Big/OptionalDevices/texture0.packed.webp', - consumables: 'XML/item_defs/vehicles/common/consumables/common.xml', + consumablesCommon: 'XML/item_defs/vehicles/common/consumables/common.xml', + consumableIcons: 'Gfx/UI/InventoryIcons/Big/Consumables', + equipmentItemImageMappings: + 'UI/Screens3/Lobby/Inventory/Equipment/EquipmentItemImage.style.yaml', } as const; diff --git a/scripts/buildAssets/consumableIcons.ts b/scripts/buildAssets/consumableIcons.ts new file mode 100644 index 000000000..731a31db8 --- /dev/null +++ b/scripts/buildAssets/consumableIcons.ts @@ -0,0 +1,149 @@ +import sharp from 'sharp'; +import { readDVPLFile } from '../../src/core/blitz/readDVPLFile'; +import { readStringDVPL } from '../../src/core/blitz/readStringDVPL'; +import { readXMLDVPL } from '../../src/core/blitz/readXMLDVPL'; +import { readYAMLDVPL } from '../../src/core/blitz/readYAMLDVPL'; +import commitMultipleFiles, { + FileChange, +} from '../../src/core/blitzkrieg/commitMultipleFiles'; +import { DATA, POI } from './constants'; +import { ConsumablesCommon } from './definitions'; + +interface Mappings { + Header: { version: number }; + StyleSheets: { + selectors: string[]; + properties: { 'bg-sprite': string }; + }[]; +} + +export async function buildConsumableIcons() { + console.log('Building consumable icons...'); + + const changes: FileChange[] = []; + // const files = await readdir(`${DATA}/${POI.consumableIcons}`); + const texture = sharp( + await readDVPLFile( + `${DATA}/${POI.consumableIcons}/texture0.packed.webp.dvpl`, + ), + ); + // const consumablesCommon = await readXMLDVPL<{ root: ConsumablesCommon }>( + // `${DATA}/${POI.consumablesCommon}.dvpl`, + // ); + // const consumablesCommonValues = Object.values(consumablesCommon.root); + + // await Promise.all( + // files + // .filter( + // (file) => file.endsWith('.txt.dvpl') && !file.endsWith('@2x.txt.dvpl'), + // ) + // .map(async (file) => { + // const name = file.replace('.txt.dvpl', ''); + // const sizes = await ( + // await readStringDVPL(`${DATA}/${POI.consumableIcons}/${file}`) + // ) + // .split('\n')[4] + // .split(' ') + // .map(Number); + // const commonEntry = consumablesCommonValues.find( + // (consumable) => consumable.icon === name, + // ); + + // if (!commonEntry) { + // console.warn(`No common entry found for ${name}; skipping...`); + // return; + // } + + // const content = ( + // await texture + // .clone() + // .extract({ + // left: sizes[0], + // top: sizes[1], + // width: sizes[2], + // height: sizes[3], + // }) + // .toBuffer() + // ).toString('base64'); + + // changes.push({ + // path: `icons/consumables/${commonEntry.id}.webp`, + // encoding: 'base64', + // content, + // }); + // }), + // ); + + const equipmentItemImageMappings = await readYAMLDVPL( + `${DATA}/${POI.equipmentItemImageMappings}.dvpl`, + ); + const consumablesCommon = await readXMLDVPL<{ root: ConsumablesCommon }>( + `${DATA}/${POI.consumablesCommon}.dvpl`, + ); + const styleSheets = Object.values(equipmentItemImageMappings.StyleSheets); + + Promise.all( + Object.values(consumablesCommon.root).map(async (consumable) => { + const styleSheet = styleSheets.find((styleSheet) => + styleSheet.selectors.includes( + `.equipment_item.${consumable.icon} * .equipment-img`, + ), + ); + + if (!styleSheet) { + throw new Error( + `No style sheet found for consumable ${consumable.icon}`, + ); + } + + const configPath = styleSheet.properties['bg-sprite'] + .replace('~res:/', '') + .replace('.psd', '.txt'); + + if (configPath.startsWith('Gfx/Shared')) { + const imagePath = `${configPath}.packed.webp.dvpl`; + const content = (await readDVPLFile(`${DATA}/${imagePath}`)).toString( + 'base64', + ); + + changes.push({ + path: `icons/consumables/${consumable.id}.webp`, + encoding: 'base64', + content, + }); + } else { + const sizes = (await readStringDVPL(`${DATA}/${configPath}.dvpl`)) + .split('\n')[4] + .split(' ') + .map(Number); + const content = ( + await texture + .clone() + .extract({ + left: sizes[0], + top: sizes[1], + width: sizes[2], + height: sizes[3], + }) + .toBuffer() + ).toString('base64'); + + changes.push({ + path: `icons/consumables/${consumable.id}.webp`, + encoding: 'base64', + content, + }); + } + }), + ); + + console.log('Committing consumable icons...'); + await commitMultipleFiles( + 'tresabhi', + 'blitzkrieg-assets', + 'main', + 'consumable icons', + changes, + true, + ); +} diff --git a/scripts/buildAssets/definitions.ts b/scripts/buildAssets/definitions.ts index 9d2285001..1b4fc3c69 100644 --- a/scripts/buildAssets/definitions.ts +++ b/scripts/buildAssets/definitions.ts @@ -183,7 +183,7 @@ interface OptionalDeviceSlotRow { [key: string]: { device0: string; device1: string }; } -interface Consumables { +export interface ConsumablesCommon { [key: string]: { id: number; userString: string; @@ -259,8 +259,8 @@ export async function buildDefinitions() { const optionalDeviceSlots = await readXMLDVPL<{ root: OptionalDeviceSlots; }>(`${DATA}/${POI.optionalDeviceSlots}.dvpl`); - const consumables = await readXMLDVPL<{ root: Consumables }>( - `${DATA}/${POI.consumables}.dvpl`, + const consumables = await readXMLDVPL<{ root: ConsumablesCommon }>( + `${DATA}/${POI.consumablesCommon}.dvpl`, ); await Promise.all( diff --git a/scripts/buildAssets/index.ts b/scripts/buildAssets/index.ts index 5618d584e..ca55b6432 100644 --- a/scripts/buildAssets/index.ts +++ b/scripts/buildAssets/index.ts @@ -1,6 +1,7 @@ import { config } from 'dotenv'; import { argv } from 'process'; import { circleFlags } from './circleFlags'; +import { buildConsumableIcons } from './consumableIcons'; import { buildDefinitions } from './definitions'; import { equipmentIcons } from './equipmentIcons'; import { buildModuleIcons } from './moduleIcons'; @@ -62,3 +63,7 @@ if (allTargets || targets?.includes('tankArmor')) { if (allTargets || targets?.includes('equipmentIcons')) { await equipmentIcons(); } + +if (allTargets || targets?.includes('consumableIcons')) { + await buildConsumableIcons(); +}