Allow Emperor gift during Guild timing choice
Verify and publish checkpoint container / container (push) Successful in 11m8s

This commit is contained in:
Quintine committed 2026-10-29 06:13:25 +11:00
1 parent a9b67a89b3
commit 93b0146de9
9 files changed
+383 -2

No files matched your search

+32
View File
@@ -0,0 +1,32 @@
'use client';
import { useId, useState } from 'react';
import type { Action, GameView } from '@/game/engine';
/** The engine projects this opportunity only to the Emperor at a supported
* Guild timing decision. Its maximum already accounts for committed spice. */
export function EmperorTimingGift({ game, act, busy }: {
game: GameView;
act: (action: Action) => void;
busy: boolean;
}) {
const id = useId();
const [raw, setRaw] = useState('1');
const offer = game.emperorGuildTimingGift;
if (!offer) return null;
const amount = /^[1-9]\d*$/.test(raw) ? Number(raw) : NaN;
const canShare = !busy && Number.isSafeInteger(amount) && amount >= 1 && amount <= offer.maximum;
const recipient = game.players.find(player => player.id === offer.recipient)?.name ?? 'your ally';
return <section className="notice min-w-0 space-y-3 break-words" aria-label="Emperor spice gift">
<h3>Share spice with {recipient}</h3>
<p className="fine">The Guild timing decision resumes after the Karama response to your gift.</p>
<label htmlFor={`${id}-amount`}>Spice to share</label>
<input id={`${id}-amount`} type="number" inputMode="numeric" min={1} max={offer.maximum}
step={1} value={raw} disabled={busy} onChange={event => setRaw(event.target.value)} />
<button type="button" className="game-action" disabled={!canShare}
onClick={() => { if (canShare) act({type:'emperorGift', amount}); }}>
Share spice
</button>
</section>;
}
+2
View File
@@ -290,6 +290,7 @@ import { CoalitionNexus } from './coalition-nexus';
import { RosterAlliance } from './roster-alliance';
import { CoalitionFunding, coalitionFundingContributions, type CoalitionFundingContribution } from './coalition-funding';
import { CoalitionEmperorAid } from './coalition-emperor-aid';
import { EmperorTimingGift } from './emperor-timing-gift';
import { NexusEmperorPayment } from './nexus-emperor-payment';
import { NexusEmperorSellerPurchase } from './nexus-emperor-seller-purchase';
import { NexusEmperorAmbassadorPurchase } from './nexus-emperor-ambassador-purchase';
@@ -3219,6 +3220,7 @@ export function GameTable({
? 'Ride the sandworm'
: 'Spoils of battle'}
</h2>
<EmperorTimingGift game={g} act={act} busy={busy} />
{g.decision.kind === 'capturedLeader' &&
(g.decision.controller ?? g.decision.owner) === me.id && (
<p className="notice">