feat: add facing orientation to parts
Replace the face/back boolean with a three-state facing (face, back, standing) seeded from setup placements. Parts now orient about the anchor at the resting face/edge, so back-down parts sit on the table instead of below it and standing parts rest on their bottom edge.
This commit is contained in:
@@ -68,9 +68,9 @@ describe('matchRoute', () => {
|
||||
describe('childrenByPath', () => {
|
||||
it('groups parts by path, ordered by index', () => {
|
||||
const parts = {
|
||||
'harbor:card#a': { path: '/deck', index: 1, face: true },
|
||||
'harbor:card#b': { path: '/deck', index: 0, face: false },
|
||||
'harbor:card#c': { path: '/community/0', index: 0, face: true },
|
||||
'harbor:card#a': { path: '/deck', index: 1, facing: 'face' },
|
||||
'harbor:card#b': { path: '/deck', index: 0, facing: 'back' },
|
||||
'harbor:card#c': { path: '/community/0', index: 0, facing: 'standing' },
|
||||
};
|
||||
expect(childrenByPath(parts)).toEqual({
|
||||
'/deck': ['harbor:card#b', 'harbor:card#a'],
|
||||
@@ -80,24 +80,24 @@ describe('childrenByPath', () => {
|
||||
});
|
||||
|
||||
describe('computeSurfacePlacements', () => {
|
||||
it('places parts on a matching route with index, stackSize, and face', () => {
|
||||
it('places parts on a matching route with index, stackSize, and facing', () => {
|
||||
const surface = makeSurface({
|
||||
layout: [{ route: '/deck', x: -100, y: 0, rotation: 0 }],
|
||||
});
|
||||
const placements = computeSurfacePlacements(surface, {
|
||||
'harbor:card#a': { path: '/deck', index: 0, face: true },
|
||||
'harbor:card#b': { path: '/deck', index: 1, face: false },
|
||||
'harbor:card#a': { path: '/deck', index: 0, facing: 'face' },
|
||||
'harbor:card#b': { path: '/deck', index: 1, facing: 'back' },
|
||||
});
|
||||
expect(placements).toHaveLength(2);
|
||||
expect(placements[0]).toMatchObject({ piece: 'harbor:card#a', index: 0, stackSize: 2, face: true });
|
||||
expect(placements[1]).toMatchObject({ piece: 'harbor:card#b', index: 1, stackSize: 2, face: false });
|
||||
expect(placements[0]).toMatchObject({ piece: 'harbor:card#a', index: 0, stackSize: 2, facing: 'face' });
|
||||
expect(placements[1]).toMatchObject({ piece: 'harbor:card#b', index: 1, stackSize: 2, facing: 'back' });
|
||||
});
|
||||
|
||||
it('drops parts with no matching route', () => {
|
||||
const surface = makeSurface({ layout: [{ route: '/deck', x: 0, y: 0, rotation: 0 }] });
|
||||
const placements = computeSurfacePlacements(surface, {
|
||||
'harbor:card#a': { path: '/deck', index: 0, face: true },
|
||||
'harbor:card#b': { path: '/elsewhere', index: 0, face: true },
|
||||
'harbor:card#a': { path: '/deck', index: 0, facing: 'face' },
|
||||
'harbor:card#b': { path: '/elsewhere', index: 0, facing: 'face' },
|
||||
});
|
||||
expect(placements).toHaveLength(1);
|
||||
expect(placements[0]!.piece).toBe('harbor:card#a');
|
||||
@@ -116,7 +116,7 @@ describe('computeSurfacePlacements', () => {
|
||||
],
|
||||
});
|
||||
const placements = computeSurfacePlacements(surface, {
|
||||
'harbor:boat#fleet': { path: '/dock/0', index: 0, face: true },
|
||||
'harbor:boat#fleet': { path: '/dock/0', index: 0, facing: 'face' },
|
||||
});
|
||||
expect(placements[0]!.candidate).toEqual({ seat: '0', x: 40, y: 5, rotation: 1 });
|
||||
});
|
||||
@@ -134,7 +134,7 @@ describe('computeSurfacePlacements', () => {
|
||||
],
|
||||
});
|
||||
const placements = computeSurfacePlacements(surface, {
|
||||
'harbor:boat#fleet': { path: '/dock/0', index: 0, face: true },
|
||||
'harbor:boat#fleet': { path: '/dock/0', index: 0, facing: 'face' },
|
||||
});
|
||||
expect(placements[0]!.candidate).toEqual({ seat: '0', x: 40, y: 5, stacking: { tilt: 2 } });
|
||||
});
|
||||
@@ -144,8 +144,8 @@ describe('computeSurfacePlacements', () => {
|
||||
layout: [{ route: '/deck', x: 0, y: 0, rotation: 0 }],
|
||||
});
|
||||
const placements = computeSurfacePlacements(surface, {
|
||||
'harbor:card#b': { path: '/deck', index: 1, face: true },
|
||||
'harbor:card#a': { path: '/deck', index: 0, face: true },
|
||||
'harbor:card#b': { path: '/deck', index: 1, facing: 'face' },
|
||||
'harbor:card#a': { path: '/deck', index: 0, facing: 'face' },
|
||||
});
|
||||
expect(placements.map((p) => p.piece)).toEqual(['harbor:card#a', 'harbor:card#b']);
|
||||
});
|
||||
@@ -155,7 +155,7 @@ describe('computeRenderState', () => {
|
||||
it('only includes enabled surfaces', () => {
|
||||
const state = {
|
||||
surfaces: { 'board#harbor': true, 'hud#hand': false },
|
||||
parts: { 'harbor:card#a': { path: '/deck', index: 0, face: true } },
|
||||
parts: { 'harbor:card#a': { path: '/deck', index: 0, facing: 'face' } },
|
||||
};
|
||||
pkg.surfaces.set(
|
||||
'board#harbor',
|
||||
|
||||
Reference in New Issue
Block a user