Allow Distrans before the first ordinary auction bid
This commit is contained in:
1 parent
34dccdfd99
commit
2ea3c58f68
19 files changed
+906
-42
No files matched your search
@@ -0,0 +1,47 @@
|
||||
'use client';
|
||||
|
||||
import type { Card } from '@/game/cards';
|
||||
import type { Action } from '@/game/engine';
|
||||
import { Button } from './ui/button';
|
||||
|
||||
export interface DistransTransferActionProps {
|
||||
card: Pick<Card, 'id'>;
|
||||
recipient: { id: string; name?: string } | undefined;
|
||||
given: Pick<Card, 'id' | 'name'> | undefined;
|
||||
reason: string | null;
|
||||
reasonId: string;
|
||||
busy: boolean;
|
||||
act: (action: Action) => void;
|
||||
}
|
||||
|
||||
export function DistransTransferAction({
|
||||
card,
|
||||
recipient,
|
||||
given,
|
||||
reason,
|
||||
reasonId,
|
||||
busy,
|
||||
act,
|
||||
}: DistransTransferActionProps) {
|
||||
const disabled = busy || !!reason || !recipient || !given;
|
||||
return (
|
||||
<Button
|
||||
className="min-h-11 whitespace-normal motion-reduce:transition-none"
|
||||
data-testid="distrans-transfer"
|
||||
disabled={disabled}
|
||||
aria-describedby={reason ? reasonId : undefined}
|
||||
onClick={() => {
|
||||
if (!disabled && recipient && given)
|
||||
act({
|
||||
type: 'card',
|
||||
card: card.id,
|
||||
target: recipient.id,
|
||||
give: given.id,
|
||||
});
|
||||
}}
|
||||
>
|
||||
Give {given?.name ?? 'a card'} to {recipient?.name ?? 'the recipient'}{' '}
|
||||
and discard Distrans
|
||||
</Button>
|
||||
);
|
||||
}
|
||||
+16
-18
@@ -2,8 +2,8 @@
|
||||
|
||||
import { useId, useState } from 'react';
|
||||
import type { Action, GameView } from '@/game/engine';
|
||||
import { Button } from './ui/button';
|
||||
import { CardInspector, CardRules } from './card-inspector';
|
||||
import { DistransTransferAction } from './distrans-transfer-action';
|
||||
|
||||
export function Distrans({
|
||||
game,
|
||||
@@ -49,6 +49,12 @@ export function Distrans({
|
||||
discard Distrans. No spice is paid. The transfer happens immediately,
|
||||
without a recipient confirmation or Karama response.
|
||||
</p>
|
||||
<p className="m-0 text-sm leading-6" aria-label="Provisional Distrans bid timing">
|
||||
Provisional bid timing: you may transfer before the first bid or pass
|
||||
on an ordinary auction lot. Once anyone bids or passes, that lot stays
|
||||
blocked while unresolved. Special auctions keep their existing
|
||||
restrictions.
|
||||
</p>
|
||||
<CardInspector card={distrans.card} />
|
||||
{choice && (
|
||||
<>
|
||||
@@ -103,23 +109,15 @@ export function Distrans({
|
||||
{reason}
|
||||
</p>
|
||||
)}
|
||||
<Button
|
||||
className="min-h-11 whitespace-normal motion-reduce:transition-none"
|
||||
disabled={busy || !!reason}
|
||||
aria-describedby={reason ? `${id}-reason` : undefined}
|
||||
onClick={() => {
|
||||
if (!busy && !reason && choice && given)
|
||||
act({
|
||||
type: 'card',
|
||||
card: distrans.card.id,
|
||||
target: choice.recipient,
|
||||
give: given.id,
|
||||
});
|
||||
}}
|
||||
>
|
||||
Give {given?.name ?? 'a card'} to {recipient?.name ?? 'the recipient'}{' '}
|
||||
and discard Distrans
|
||||
</Button>
|
||||
<DistransTransferAction
|
||||
card={distrans.card}
|
||||
recipient={choice ? { id: choice.recipient, name: recipient?.name } : undefined}
|
||||
given={given}
|
||||
reason={reason}
|
||||
reasonId={`${id}-reason`}
|
||||
busy={busy}
|
||||
act={act}
|
||||
/>
|
||||
{!!choice?.unavailable.length && (
|
||||
<div
|
||||
className="flex min-w-0 flex-col gap-3"
|
||||
|
||||
@@ -3,6 +3,7 @@ import { TraitorDecisionPromises } from './traitor-decision-promises';
|
||||
import { MovementPromises } from './movement-promises';
|
||||
import { HomeworldEcazDuke } from './homeworld-ecaz-duke';
|
||||
import { integerInputValue } from '../lib/integer-input';
|
||||
import { normalAuctionHandBlock } from '@/game/normal-auction';
|
||||
import { EcazSetup } from './ecaz-setup';
|
||||
import { StormCardInspector, StormCardLogInspector } from './storm-cards';
|
||||
import { stormCardDistance } from '@/game/storm-cards';
|
||||
@@ -4319,6 +4320,8 @@ export function GameTable({
|
||||
</label>
|
||||
<p className="fine">
|
||||
Minimum bid: {minimumBid} spice.
|
||||
{normalAuctionHandBlock(me.hand?.length ?? me.handCount ?? me.handLimit, me.handLimit) &&
|
||||
' Your Treachery hand is full; pass this bid.'}
|
||||
{maximumBid < minimumBid &&
|
||||
' You cannot afford a higher bid; pass this card.'}
|
||||
</p>
|
||||
@@ -4329,7 +4332,8 @@ export function GameTable({
|
||||
amount: bidAmount,
|
||||
...payment,
|
||||
},
|
||||
!Number.isSafeInteger(bidAmount) ||
|
||||
!!normalAuctionHandBlock(me.hand?.length ?? me.handCount ?? me.handLimit, me.handLimit) ||
|
||||
!Number.isSafeInteger(bidAmount) ||
|
||||
bidAmount < minimumBid ||
|
||||
bidAmount > maximumBid,
|
||||
)}
|
||||
|
||||
Reference in new issue
Block a user