Automatically return the full combined hand when it is the only legal special-Karama return. Preserve real choices and restore the suspended response or auction payment through the same settlement. Record the actual blind draw as owner-only historical card faces, with a bound integrity receipt; legacy forced saves describe held-card history truthfully. Add readable private history and enlarged inspectors. Both manual and forced returns publish only a faction/action completion tag. Wake idle legacy exchanges through production recovery without writes for real choices. Keep provisional auction funding rules and release gates. Validation: types, lint, 5150 offline tests, build and 49 HTTP tests passed. Independent review resolved history substitution and root review completed idle recovery wiring. New tests cover 1-4 forced draws, real choices, overlays, exact saved history, immutable rejection, all four legal AI paths, production competing actions/recovery, private views and custody. One genuine Advanced four-player sample completed 158 actions with 4 JSON restores and no rejected action; no difficulty tuning. Browser QA QUTHVPTT used genuine Advanced setup and conserved Bidding positions. The actual power returned four cards without a prompt; private history/enlargement and exact refresh worked. Phone panel fit without horizontal overflow with 44px inspector controls. Screenshot capture timed out; complete visual acceptance and transient notice capture remain open. Preserved every prior row across all ten tables, including 1586 rooms and 3354 seats. New QA/integration records bring totals to 1626 rooms and 3442 seats. No reset, restart or automation.
32 lines
1.3 KiB
TypeScript
32 lines
1.3 KiB
TypeScript
'use client';
|
|
|
|
import type { GameView } from '@/game/engine';
|
|
import { CardInspector, CardRules } from './card-inspector';
|
|
|
|
/** Historical observations arrive only in the inspecting player's projection. */
|
|
export function HarkonnenExchangeInspection({ game }: { game: GameView }) {
|
|
const record = game.harkonnenExchangeInspection;
|
|
if (!record || record.owner !== game.me) return null;
|
|
const target = game.players.find(player => player.id === record.target);
|
|
return (
|
|
<details className="notice harkonnen-exchange-inspection">
|
|
<summary>Your Harkonnen inspection · Turn {record.turn}</summary>
|
|
<p>
|
|
{record.kind === 'draw'
|
|
? `Cards you took and inspected from ${target?.name ?? 'the other player'} during Bidding.`
|
|
: `Cards in your hand before the automatic return to ${target?.name ?? 'the other player'} during Bidding.`}
|
|
{' '}This is a record of what you saw then. These cards may have changed hands since.
|
|
</p>
|
|
<ul className="grid list-none gap-3 p-0 sm:grid-cols-2">
|
|
{record.cards.map(card => (
|
|
<li key={card.id} className="min-w-0 rounded border border-white/15 p-3">
|
|
<strong>{card.name}</strong>
|
|
<CardRules card={card} />
|
|
<CardInspector card={card} />
|
|
</li>
|
|
))}
|
|
</ul>
|
|
</details>
|
|
);
|
|
}
|