mirror of
https://github.com/exogen/t2-mapper.git
synced 2026-01-19 20:25:01 +00:00
add ifl helpers
This commit is contained in:
parent
a05153303e
commit
e9ccf22f54
61
scripts/inspect-ifl.ts
Normal file
61
scripts/inspect-ifl.ts
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
import fs from "node:fs";
|
||||
import { inspect, parseArgs } from "node:util";
|
||||
import { parseImageFrameList } from "@/src/ifl";
|
||||
import { getFilePath } from "@/src/manifest";
|
||||
|
||||
async function run() {
|
||||
const { values, positionals } = parseArgs({
|
||||
allowPositionals: true,
|
||||
options: {
|
||||
name: {
|
||||
type: "string",
|
||||
short: "n",
|
||||
},
|
||||
list: {
|
||||
type: "boolean",
|
||||
short: "l",
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
if (values.list) {
|
||||
if (values.name || positionals[0]) {
|
||||
console.error("Cannot specify --list (-l) with other options.");
|
||||
return 1;
|
||||
}
|
||||
const manifest = (await import("../public/manifest.json")).default;
|
||||
const fileNames = Object.keys(manifest);
|
||||
console.log(
|
||||
fileNames
|
||||
.map((f) => f.match(/^textures\/skins\/(.+)\.ifl$/))
|
||||
.filter(Boolean)
|
||||
.map((match) => match[1])
|
||||
.join("\n")
|
||||
);
|
||||
return;
|
||||
} else if (
|
||||
(values.name && positionals[0]) ||
|
||||
(!values.name && !positionals[0])
|
||||
) {
|
||||
console.error(
|
||||
"Must specify exactly one of --name (-n) or a positional filename."
|
||||
);
|
||||
return 1;
|
||||
}
|
||||
|
||||
let framesFile = positionals[0];
|
||||
if (values.name) {
|
||||
const resourcePath = `textures/skins/${values.name}.ifl`;
|
||||
framesFile = getFilePath(resourcePath);
|
||||
}
|
||||
const missionScript = fs.readFileSync(framesFile, "utf8");
|
||||
console.log(
|
||||
inspect(parseImageFrameList(missionScript), {
|
||||
colors: true,
|
||||
depth: Infinity,
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
const code = await run();
|
||||
process.exit(code ?? 0);
|
||||
15
src/ifl.ts
Normal file
15
src/ifl.ts
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
export function parseImageFrameList(source: string) {
|
||||
const lines = source
|
||||
.split(/(?:\r\n|\r|\n)/g)
|
||||
.map((line) => line.trim())
|
||||
.filter(Boolean);
|
||||
return lines.map((line) => {
|
||||
const fileWithCount = line.match(/^(.+)\s(\d+)$/);
|
||||
if (fileWithCount) {
|
||||
const frameCount = parseInt(fileWithCount[2], 10);
|
||||
return { name: fileWithCount[1], frameCount };
|
||||
} else {
|
||||
return { name: line, frameCount: 1 };
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
@ -1,3 +1,4 @@
|
|||
import { parseImageFrameList } from "./ifl";
|
||||
import { getActualResourcePath, getSource } from "./manifest";
|
||||
import { parseMissionScript } from "./mission";
|
||||
import { parseTerrainBuffer } from "./terrain";
|
||||
|
|
@ -45,6 +46,10 @@ export function interiorTextureToUrl(name: string, fallbackUrl?: string) {
|
|||
return getUrlForPath(`textures/${name}.png`, fallbackUrl);
|
||||
}
|
||||
|
||||
export function textureFrameToUrl(fileName: string) {
|
||||
return getUrlForPath(`textures/skins/${fileName}`);
|
||||
}
|
||||
|
||||
export function shapeTextureToUrl(name: string, fallbackUrl?: string) {
|
||||
name = name.replace(/\.\d+$/, "");
|
||||
return getUrlForPath(`textures/skins/${name}.png`, fallbackUrl);
|
||||
|
|
@ -82,3 +87,10 @@ export async function loadTerrain(fileName: string) {
|
|||
const terrainBuffer = await res.arrayBuffer();
|
||||
return parseTerrainBuffer(terrainBuffer);
|
||||
}
|
||||
|
||||
export async function loadImageFrameList(iflPath: string) {
|
||||
const url = getUrlForPath(iflPath);
|
||||
const res = await fetch(url);
|
||||
const source = await res.text();
|
||||
return parseImageFrameList(source);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue