make character customization projection aware

This commit is contained in:
jwinterm
2026-07-06 06:38:19 -04:00
parent c89c01e5f1
commit f505a4fb8a
8 changed files with 174 additions and 37 deletions
+35
View File
@@ -0,0 +1,35 @@
const fs = require('fs');
const path = require('path');
const vm = require('vm');
function loadCharSprites() {
const context = {
console,
window: { console }
};
context.window.window = context.window;
vm.runInNewContext(
fs.readFileSync(path.join(__dirname, '../html/js/render/charSprites.js'), 'utf8'),
context
);
return context.window.RK;
}
describe('roguelike character sprites', () => {
test('equipment stays fixed color unless an asset explicitly opts into tinting', () => {
const RK = loadCharSprites();
const parts = RK.charOverlayParts({
avatar: 'char-wizard',
tint: 'gold',
colors: { base: 'gold', body: 'moss', head: 'teal' },
equipment: { body: 'mail', head: 'helm', shield: 'round', weapon: 'sword' }
});
expect(parts).toEqual(expect.arrayContaining([
expect.objectContaining({ slot: 'body', id: 'mail', tint: 'none', colorable: false }),
expect.objectContaining({ slot: 'head', id: 'helm', tint: 'none', colorable: false }),
expect.objectContaining({ slot: 'shield', id: 'round', tint: 'none', colorable: false }),
expect.objectContaining({ slot: 'weapon', id: 'sword', tint: 'none', colorable: false })
]));
});
});
+19
View File
@@ -37,6 +37,10 @@ function loadRenderKit() {
'monero-knight': { id: 'monero-knight', label: 'Monero Knight', pack: 'generated-skins' }
};
RK.isSkin = id => !!RK.SKINS[id];
RK.CHAR_TINTS = {
none: { id: 'none', label: 'Natural', color: null },
gold: { id: 'gold', label: 'Gold', color: '#d29922' }
};
RK.CHARS = { 'char-ranger': { id: 'char-ranger', label: 'Ranger', frame: 432 } };
RK.isChar = id => !!RK.CHARS[id];
@@ -87,6 +91,21 @@ describe('render pack visual resolver', () => {
expect(compat.model.url).toContain('survivorFemaleA.glb');
});
test('iso floor uses a flat tile instead of a raised block tile', () => {
const RK = loadRenderKit();
expect(RK.isoAssets.tiles.floor).toContain('planks_S.png');
expect(RK.isoAssets.tiles.floor).not.toContain('stone_S.png');
});
test('projection visuals expose the saved base tint as a render color', () => {
const RK = loadRenderKit();
const visual = RK.avatarVisuals.resolve(
{ avatar: 'char-ranger', colors: { base: 'gold' }, tint: 'gold' },
{ projection: 'iso' }
);
expect(RK.avatarVisuals.tintColorFor(visual.appearance)).toBe('#d29922');
});
test('renderer factory falls back when premium modes are locked', () => {
const RK = loadRenderKit();
RK.setEntitlementSnapshot({ totalCreditsPurchased: 0, premium: false, packs: {} });