Fix caching, Limits placement, and explain the board better

This commit is contained in:
Jesse
2026-07-31 23:34:18 -04:00
parent 2eca9de09f
commit dd300ac154
10 changed files with 466 additions and 26 deletions
+17 -5
View File
@@ -8,6 +8,7 @@
import type { Game } from './game.ts';
import {
actionMenu,
handPlayable,
currentActor,
fromSave,
newGame,
@@ -130,12 +131,15 @@ function render(): void {
: '<div></div>';
continue;
}
// The full explanation goes in `title` so hovering any card says what it does, with a short
// version printed on the card itself — a name alone tells a player nothing once it is played.
cells +=
`<div class="cell ${cell.running ? 'run ' : ''}${cell.kind === 'office' ? 'office ' : ''}` +
`${cell.kind === 'modifier' ? 'modifier ' : ''}${spots ? 'legal' : ''}"` +
`${spots ? ` data-at="${r},${c}"` : ''}>` +
`${spots ? ` data-at="${r},${c}"` : ''} title="${esc(cell.label)} — ${esc(cell.what)}">` +
`<div class="nm">${esc(cell.label)}</div>` +
`<div class="dim coord">(${r},${c})</div>` +
`<div class="dim what">${esc(short(cell.what))}</div>` +
(cell.enhancements.length
? `<div class="enh">${cell.enhancements.map(esc).join(' · ')}</div>`
: '') +
@@ -194,16 +198,18 @@ function render(): void {
.join('');
// Name AND effect. A hand of names alone tells a player nothing about what they can do.
const cardRow = (name: string, why: string): string =>
`<div class="handcard"><b>${esc(name)}</b>` +
const cardRow = (name: string, why: string, playable: boolean | null): string =>
`<div class="handcard${playable === false ? ' unplayable' : ''}"><b>${esc(name)}</b>` +
(playable === false ? ' <span class="tag">not playable yet</span>' : '') +
(why ? `<div class="dim what">${esc(why)}</div>` : '') +
`</div>`;
const canPlay = handPlayable(game);
$('hand').innerHTML = f.hand.length
? f.hand.map((h, i) => cardRow(h, f.handWhat[i] ?? '')).join('')
? f.hand.map((h, i) => cardRow(h, f.handWhat[i] ?? '', canPlay[i] ?? null)).join('')
: '<span class="dim">empty</span>';
$('depts').innerHTML = f.departments.length
? f.departments.map((d, i) => cardRow(d, f.departmentsWhat[i] ?? '')).join('')
? f.departments.map((d, i) => cardRow(d, f.departmentsWhat[i] ?? '', null)).join('')
: '<span class="dim">none</span>';
const total = f.trackSupply.reduce((n, t) => n + t.left, 0);
@@ -235,6 +241,12 @@ function render(): void {
save();
}
/** First clause only — the cards are small, and the full text is on the tooltip. */
function short(what: string): string {
const head = what.split(' · ')[0] ?? what;
return head.length > 64 ? head.slice(0, 61) + '…' : head;
}
function boxes(items: string[], cap: number): string {
let out = '';
for (let i = 0; i < Math.max(cap, items.length); i++) {