feat: upgrade city stay exploration
This commit is contained in:
@@ -21,11 +21,14 @@ const expectedBaseMappings = {
|
||||
'unit-shu-infantry': 'exploration-shu-infantry'
|
||||
};
|
||||
const expectedNamedTextureFallbacks = {
|
||||
'exploration-huang-quan': 'unit-shu-officer',
|
||||
'exploration-jian-yong': 'unit-shu-officer',
|
||||
'exploration-mi-zhu': 'unit-shu-officer',
|
||||
'exploration-zhuge-liang': 'unit-shu-officer',
|
||||
'exploration-zhuo-recruiting-clerk': 'unit-shu-officer',
|
||||
'exploration-zhuo-villager': 'unit-shu-infantry',
|
||||
'exploration-zhuo-quartermaster': 'unit-shu-officer',
|
||||
'exploration-zou-jing': 'unit-shu-officer',
|
||||
'exploration-jian-yong': 'unit-shu-officer'
|
||||
'exploration-zou-jing': 'unit-shu-officer'
|
||||
};
|
||||
const expectedSceneNpcTextureKeys = [
|
||||
{
|
||||
@@ -136,17 +139,22 @@ assert.deepEqual(
|
||||
|
||||
deployedFiles.forEach((fileName) => {
|
||||
const path = join(characterDirectory, fileName);
|
||||
const dimensions = webpDimensions(path);
|
||||
const inspection = inspectWebp(path);
|
||||
assert.equal(
|
||||
dimensions.width,
|
||||
inspection.width,
|
||||
expectedWidth,
|
||||
`${path}: expected ${expectedWidth}px width for 16 frames per direction.`
|
||||
);
|
||||
assert.equal(
|
||||
dimensions.height,
|
||||
inspection.height,
|
||||
expectedHeight,
|
||||
`${path}: expected ${expectedHeight}px height for four direction rows.`
|
||||
);
|
||||
assert.equal(
|
||||
inspection.hasAlpha,
|
||||
true,
|
||||
`${path}: exploration character sheets must preserve transparent backgrounds.`
|
||||
);
|
||||
});
|
||||
|
||||
console.log(
|
||||
@@ -172,7 +180,7 @@ function readStringMap(source, mappingName) {
|
||||
return mappings;
|
||||
}
|
||||
|
||||
function webpDimensions(path) {
|
||||
function inspectWebp(path) {
|
||||
const bytes = readFileSync(path);
|
||||
assert(
|
||||
bytes.subarray(0, 4).toString('ascii') === 'RIFF' &&
|
||||
@@ -181,6 +189,8 @@ function webpDimensions(path) {
|
||||
);
|
||||
|
||||
let offset = 12;
|
||||
let dimensions;
|
||||
let hasAlpha = false;
|
||||
while (offset + 8 <= bytes.length) {
|
||||
const chunkType = bytes.subarray(offset, offset + 4).toString('ascii');
|
||||
const chunkSize = bytes.readUInt32LE(offset + 4);
|
||||
@@ -191,20 +201,22 @@ function webpDimensions(path) {
|
||||
);
|
||||
|
||||
if (chunkType === 'VP8X') {
|
||||
return {
|
||||
dimensions = {
|
||||
width: bytes.readUIntLE(payloadOffset + 4, 3) + 1,
|
||||
height: bytes.readUIntLE(payloadOffset + 7, 3) + 1
|
||||
};
|
||||
}
|
||||
if (chunkType === 'VP8L') {
|
||||
hasAlpha ||= (bytes[payloadOffset] & 0x10) !== 0;
|
||||
} else if (chunkType === 'ALPH') {
|
||||
hasAlpha = true;
|
||||
} else if (chunkType === 'VP8L') {
|
||||
const bits = bytes.readUInt32LE(payloadOffset + 1);
|
||||
return {
|
||||
dimensions ??= {
|
||||
width: (bits & 0x3fff) + 1,
|
||||
height: ((bits >>> 14) & 0x3fff) + 1
|
||||
};
|
||||
}
|
||||
if (chunkType === 'VP8 ') {
|
||||
return {
|
||||
hasAlpha ||= (bits & 0x10000000) !== 0;
|
||||
} else if (chunkType === 'VP8 ') {
|
||||
dimensions ??= {
|
||||
width: bytes.readUInt16LE(payloadOffset + 6) & 0x3fff,
|
||||
height: bytes.readUInt16LE(payloadOffset + 8) & 0x3fff
|
||||
};
|
||||
@@ -213,5 +225,6 @@ function webpDimensions(path) {
|
||||
offset = payloadOffset + chunkSize + (chunkSize % 2);
|
||||
}
|
||||
|
||||
throw new Error(`${path}: could not read WebP dimensions.`);
|
||||
assert(dimensions, `${path}: could not read WebP dimensions.`);
|
||||
return { ...dimensions, hasAlpha };
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user