Preserve Emperor gift opportunity before bot Extortion
Verify and publish checkpoint container / container (push) Successful in 10m54s
Verify and publish checkpoint container / container (push) Successful in 10m54s
This commit is contained in:
1 parent
a6be17fc5d
commit
7c1f4b4e09
13 files changed
+370
-13
No files matched your search
@@ -0,0 +1,41 @@
|
||||
'use client';
|
||||
|
||||
import type { Action } from '@/game/engine';
|
||||
import { Button } from './ui/button';
|
||||
|
||||
/** The same public opportunity is shown regardless of the Emperor's spice. */
|
||||
export type EmperorExtortionPriorityView = {
|
||||
event: string;
|
||||
recipient: string;
|
||||
canContinue: boolean;
|
||||
};
|
||||
|
||||
export type EmperorExtortionPriorityProps = {
|
||||
game: {
|
||||
emperorExtortionPriority: EmperorExtortionPriorityView | null;
|
||||
players: readonly { id: string; name: string }[];
|
||||
};
|
||||
act: (action: Action) => void;
|
||||
busy: boolean;
|
||||
};
|
||||
|
||||
/** The payer's normal Extortion choice remains pending until the Emperor
|
||||
* completes this optional alliance opportunity. */
|
||||
export function EmperorExtortionPriority({ game, act, busy }: EmperorExtortionPriorityProps) {
|
||||
const priority = game.emperorExtortionPriority;
|
||||
if (!priority) return null;
|
||||
const event = priority.event;
|
||||
const recipient = game.players.find(player => player.id === priority.recipient)?.name ?? 'the ally';
|
||||
const canAct = () => !busy && game.emperorExtortionPriority === priority &&
|
||||
priority.event === event && typeof event === 'string' && event.length > 0 && priority.canContinue;
|
||||
|
||||
return <section className="notice space-y-3" aria-label="Emperor Extortion opportunity" aria-live="polite">
|
||||
<h3>Emperor alliance opportunity</h3>
|
||||
<p>Before {recipient} makes the Extortion choice, the Emperor may share spice with their ally. The existing gift control shows any available amount.</p>
|
||||
{priority.canContinue ? <Button className="game-action min-h-11 whitespace-normal"
|
||||
data-testid="emperor-extortion-continue" disabled={!canAct()}
|
||||
onClick={() => { if (canAct()) act({type:'emperorExtortionContinue', event}); }}>
|
||||
Continue to Extortion
|
||||
</Button> : <p>Waiting for the Emperor to continue.</p>}
|
||||
</section>;
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
'use client';
|
||||
import { SaphoArrivalOrder } from './sapho-arrival-order';
|
||||
import { SaphoStationPriority } from './sapho-station-priority';
|
||||
import { EmperorExtortionPriority } from './emperor-extortion-priority';
|
||||
import { RicheseBidPromisePanel } from './richese-bid-promise-panel';
|
||||
import { EarlyRicheseBidPromises } from './early-richese-bid-promises';
|
||||
import { TravelPromises } from './travel-promises';
|
||||
@@ -1536,6 +1537,7 @@ export function GameTable({
|
||||
<EcazLoyaltyCard loyalty={g.ecazLoyalty} />
|
||||
<MoritaniTerrorSupply game={g} />
|
||||
<MoritaniExtortionNotice game={g} />
|
||||
{g.emperorExtortionPriority && <EmperorExtortionPriority game={g} act={act} busy={reactionBusy} />}
|
||||
{g.saphoStationPriority && <SaphoStationPriority game={g} act={act}
|
||||
busy={transportBusy || !!g.roomControl?.paused || !!g.roomControl?.closed || !!me.autopilot} />}
|
||||
{g.saphoArrivalOrder && <SaphoArrivalOrder view={g.saphoArrivalOrder} me={g.me}
|
||||
|
||||
Reference in new issue
Block a user