mirror of
https://github.com/blitzkit/blitzkit.git
synced 2026-10-24 12:09:51 +02:00
provision icons
This commit is contained in:
1 parent
90ad923672
commit
8a3e57637d
2 files changed
+112
-189
No files matched your search
@@ -1,189 +0,0 @@
|
|||||||
import sharp from "sharp";
|
|
||||||
import { parsePackedSpriteRect } from "../core/blitz/parsePackedSpriteRect";
|
|
||||||
import { AssetUploader } from "../core/github/assetUploader";
|
|
||||||
import { vfs } from "./constants";
|
|
||||||
import { ConsumablesCommon, ProvisionsCommon } from "./definitions";
|
|
||||||
|
|
||||||
interface Mappings {
|
|
||||||
Header: { version: number };
|
|
||||||
StyleSheets: {
|
|
||||||
selectors: string[];
|
|
||||||
properties: { "bg-sprite": string };
|
|
||||||
}[];
|
|
||||||
}
|
|
||||||
|
|
||||||
const listItemsPattern = /<items path="(.+)\.xml"\/>/g;
|
|
||||||
|
|
||||||
export async function consumableProvisionIcons() {
|
|
||||||
console.log("Building consumable and provision icons...");
|
|
||||||
|
|
||||||
using uploader = new AssetUploader("consumable and provision icons");
|
|
||||||
const styles = [
|
|
||||||
"UI/Styles/Lobby/Inventory/InventoryNormalStyles.yaml",
|
|
||||||
"UI/Styles/Lobby/Inventory/Event/InventoryBigStyles.yaml",
|
|
||||||
"UI/Styles/Lobby/Inventory/Event/InventoryNormalStyles.yaml",
|
|
||||||
"UI/Screens3/Lobby/Inventory/Equipment/EquipmentItemImage.style.yaml",
|
|
||||||
"UI/Screens/Battle/Styles/BattleEquipmentStyles.yaml",
|
|
||||||
];
|
|
||||||
const styleSheets = await Promise.all(
|
|
||||||
styles.map(async (path) =>
|
|
||||||
Object.values((await vfs.yaml<Mappings>(`Data/${path}`)).StyleSheets),
|
|
||||||
),
|
|
||||||
).then((array) => array.flat());
|
|
||||||
|
|
||||||
for (const match of (
|
|
||||||
await vfs.text(`Data/XML/item_defs/vehicles/common/consumables/list.xml`)
|
|
||||||
).matchAll(listItemsPattern)) {
|
|
||||||
const consumablesCommon = await vfs.xml<{
|
|
||||||
root: ConsumablesCommon;
|
|
||||||
}>(`Data/XML/item_defs/vehicles/common/consumables/${match[1]}.xml`);
|
|
||||||
|
|
||||||
for (const consumable of Object.values(consumablesCommon.root)) {
|
|
||||||
const styleSheet = styleSheets.find((styleSheet) =>
|
|
||||||
styleSheet.selectors.some((selector) =>
|
|
||||||
selector.includes(`${consumable.icon} `),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!styleSheet) {
|
|
||||||
console.warn(
|
|
||||||
`No style sheet found for consumable ${consumable.icon}; skipping...`,
|
|
||||||
);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
const configPath = styleSheet.properties["bg-sprite"]
|
|
||||||
.replace("~res:/", "")
|
|
||||||
.replace(".psd", "")
|
|
||||||
.replace(".txt", "");
|
|
||||||
|
|
||||||
if (await vfs.resolve(`Data/${configPath}.packed.webp`)) {
|
|
||||||
const packedBuffer = await vfs.file(`Data/${configPath}.packed.webp`);
|
|
||||||
const consumablesTexture = sharp(packedBuffer);
|
|
||||||
const sizes = parsePackedSpriteRect(packedBuffer);
|
|
||||||
let content: Buffer;
|
|
||||||
|
|
||||||
if (sizes) {
|
|
||||||
content = await extractPackedIcon(
|
|
||||||
consumablesTexture,
|
|
||||||
sizes,
|
|
||||||
`consumable ${consumable.icon}`,
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
content = await consumablesTexture.trim({ threshold: 80 }).toBuffer();
|
|
||||||
}
|
|
||||||
|
|
||||||
await uploader.add({
|
|
||||||
path: `icons/consumables/${consumable.id}.webp`,
|
|
||||||
content,
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
const consumablesTexture = sharp(
|
|
||||||
await vfs.file(
|
|
||||||
`${`Data/${configPath}`
|
|
||||||
.split("/")
|
|
||||||
.slice(0, -1)
|
|
||||||
.join("/")}/texture0.packed.webp`,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
const sizes = (await vfs.text(`Data/${configPath}.txt`))
|
|
||||||
.split("\n")[4]
|
|
||||||
.split(" ")
|
|
||||||
.map(Number);
|
|
||||||
const content = await consumablesTexture
|
|
||||||
.clone()
|
|
||||||
.extract({
|
|
||||||
left: sizes[0],
|
|
||||||
top: sizes[1],
|
|
||||||
width: sizes[2],
|
|
||||||
height: sizes[3],
|
|
||||||
})
|
|
||||||
.toBuffer();
|
|
||||||
|
|
||||||
await uploader.add({
|
|
||||||
path: `icons/consumables/${consumable.id}.webp`,
|
|
||||||
content,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const match of (
|
|
||||||
await vfs.text(`Data/XML/item_defs/vehicles/common/provisions/list.xml`)
|
|
||||||
).matchAll(listItemsPattern)) {
|
|
||||||
const provisionsCommon = await vfs.xml<{
|
|
||||||
root: ProvisionsCommon;
|
|
||||||
}>(`Data/XML/item_defs/vehicles/common/provisions/${match[1]}.xml`);
|
|
||||||
|
|
||||||
for (const provision of Object.values(provisionsCommon.root)) {
|
|
||||||
const styleSheet = styleSheets.find((styleSheet) =>
|
|
||||||
styleSheet.selectors.some((selector) =>
|
|
||||||
selector.includes(`${provision.icon} `),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!styleSheet) {
|
|
||||||
console.warn(
|
|
||||||
`No style sheet found for provision ${provision.icon}; skipping...`,
|
|
||||||
);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
const configPath = styleSheet.properties["bg-sprite"]
|
|
||||||
.replace("~res:/", "")
|
|
||||||
.replace(".psd", "")
|
|
||||||
.replace(".txt", "");
|
|
||||||
|
|
||||||
if (await vfs.resolve(`Data/${configPath}.packed.webp`)) {
|
|
||||||
const packedBuffer = await vfs.file(`Data/${configPath}.packed.webp`);
|
|
||||||
const provisionsTexture = sharp(packedBuffer);
|
|
||||||
const sizes = parsePackedSpriteRect(packedBuffer);
|
|
||||||
let content: Buffer;
|
|
||||||
|
|
||||||
if (sizes) {
|
|
||||||
content = await extractPackedIcon(
|
|
||||||
provisionsTexture,
|
|
||||||
sizes,
|
|
||||||
`provision ${provision.icon}`,
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
content = await provisionsTexture.trim({ threshold: 80 }).toBuffer();
|
|
||||||
}
|
|
||||||
|
|
||||||
await uploader.add({
|
|
||||||
path: `icons/provisions/${provision.id}.webp`,
|
|
||||||
content,
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
const provisionsTexture = sharp(
|
|
||||||
await vfs.file(
|
|
||||||
`${`Data/${configPath}`
|
|
||||||
.split("/")
|
|
||||||
.slice(0, -1)
|
|
||||||
.join("/")}/texture0.packed.webp`,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
const sizes = (await vfs.text(`Data/${configPath}.txt`))
|
|
||||||
.split("\n")[4]
|
|
||||||
.split(" ")
|
|
||||||
.map(Number);
|
|
||||||
const content = await provisionsTexture
|
|
||||||
.clone()
|
|
||||||
.extract({
|
|
||||||
left: sizes[0],
|
|
||||||
top: sizes[1],
|
|
||||||
width: sizes[2],
|
|
||||||
height: sizes[3],
|
|
||||||
})
|
|
||||||
.toBuffer();
|
|
||||||
|
|
||||||
await uploader.add({
|
|
||||||
path: `icons/provisions/${provision.id}.webp`,
|
|
||||||
content,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
await uploader.flush();
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,112 @@
|
|||||||
|
import type { ProvisionsCommon } from "@blitzkit/core";
|
||||||
|
import type { APIContext, GetStaticPathsItem } from "astro";
|
||||||
|
import sharp from "sharp";
|
||||||
|
import { extractPackedIcon } from "../../../../core/blitz/extractPackedIcon";
|
||||||
|
import { parsePackedSpriteRect } from "../../../../core/blitz/parsePackedSpriteRect";
|
||||||
|
import { mixStaticPaths } from "../../../../core/blitzkit/mixStaticPaths";
|
||||||
|
import { vfs } from "../../../../core/blitzkit/vfs";
|
||||||
|
import { getStaticPaths as _getStaticPaths } from "../../_index";
|
||||||
|
|
||||||
|
interface Mappings {
|
||||||
|
Header: { version: number };
|
||||||
|
StyleSheets: {
|
||||||
|
selectors: string[];
|
||||||
|
properties: { "bg-sprite": string };
|
||||||
|
}[];
|
||||||
|
}
|
||||||
|
|
||||||
|
const listItemsPattern = /<items path="(.+)\.xml"\/>/g;
|
||||||
|
|
||||||
|
export const getStaticPaths = mixStaticPaths(_getStaticPaths, async () => {
|
||||||
|
const paths: GetStaticPathsItem[] = [];
|
||||||
|
|
||||||
|
const styles = [
|
||||||
|
"UI/Styles/Lobby/Inventory/InventoryNormalStyles.yaml",
|
||||||
|
"UI/Styles/Lobby/Inventory/Event/InventoryBigStyles.yaml",
|
||||||
|
"UI/Styles/Lobby/Inventory/Event/InventoryNormalStyles.yaml",
|
||||||
|
"UI/Screens3/Lobby/Inventory/Equipment/EquipmentItemImage.style.yaml",
|
||||||
|
"UI/Screens/Battle/Styles/BattleEquipmentStyles.yaml",
|
||||||
|
];
|
||||||
|
const styleSheets = await Promise.all(
|
||||||
|
styles.map(async (path) =>
|
||||||
|
Object.values((await vfs.yaml<Mappings>(`Data/${path}`)).StyleSheets),
|
||||||
|
),
|
||||||
|
).then((array) => array.flat());
|
||||||
|
|
||||||
|
for (const match of (
|
||||||
|
await vfs.text(`Data/XML/item_defs/vehicles/common/provisions/list.xml`)
|
||||||
|
).matchAll(listItemsPattern)) {
|
||||||
|
const provisionsCommon = await vfs.xml<{
|
||||||
|
root: ProvisionsCommon;
|
||||||
|
}>(`Data/XML/item_defs/vehicles/common/provisions/${match[1]}.xml`);
|
||||||
|
|
||||||
|
for (const provision of Object.values(provisionsCommon.root)) {
|
||||||
|
const styleSheet = styleSheets.find((styleSheet) =>
|
||||||
|
styleSheet.selectors.some((selector) =>
|
||||||
|
selector.includes(`${provision.icon} `),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!styleSheet) {
|
||||||
|
console.warn(
|
||||||
|
`No style sheet found for provision ${provision.icon}; skipping...`,
|
||||||
|
);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const path = styleSheet.properties["bg-sprite"]
|
||||||
|
.replace("~res:/", "")
|
||||||
|
.replace(".psd", "")
|
||||||
|
.replace(".txt", "");
|
||||||
|
|
||||||
|
paths.push({
|
||||||
|
props: { path },
|
||||||
|
params: { id: provision.id },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return paths;
|
||||||
|
});
|
||||||
|
|
||||||
|
export async function GET({ props }: APIContext<{ path: string }>) {
|
||||||
|
let buffer: Buffer;
|
||||||
|
|
||||||
|
if (await vfs.resolve(`Data/${props.path}.packed.webp`)) {
|
||||||
|
const packedBuffer = await vfs.file(`Data/${props.path}.packed.webp`);
|
||||||
|
const provisionsTexture = sharp(packedBuffer);
|
||||||
|
const sizes = parsePackedSpriteRect(packedBuffer);
|
||||||
|
|
||||||
|
if (sizes) {
|
||||||
|
buffer = await extractPackedIcon(provisionsTexture, sizes);
|
||||||
|
} else {
|
||||||
|
buffer = await provisionsTexture.trim({ threshold: 80 }).toBuffer();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
const provisionsTexture = sharp(
|
||||||
|
await vfs.file(
|
||||||
|
`${`Data/${props.path}`
|
||||||
|
.split("/")
|
||||||
|
.slice(0, -1)
|
||||||
|
.join("/")}/texture0.packed.webp`,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
const sizes = (await vfs.text(`Data/${props.path}.txt`))
|
||||||
|
.split("\n")[4]
|
||||||
|
.split(" ")
|
||||||
|
.map(Number);
|
||||||
|
buffer = await provisionsTexture
|
||||||
|
.clone()
|
||||||
|
.extract({
|
||||||
|
left: sizes[0],
|
||||||
|
top: sizes[1],
|
||||||
|
width: sizes[2],
|
||||||
|
height: sizes[3],
|
||||||
|
})
|
||||||
|
.toBuffer();
|
||||||
|
}
|
||||||
|
|
||||||
|
const bytes = new Uint8Array(buffer);
|
||||||
|
|
||||||
|
return new Response(bytes);
|
||||||
|
}
|
||||||
Reference in new issue
Block a user