Support immediate payments in group travel deals
Verify and publish checkpoint container / container (push) Successful in 10m49s

This commit is contained in:
Quintine committed 2026-10-29 17:41:58 +11:00
1 parent 3987c5c16b
commit 6c1530382d
10 files changed
+207 -24

No files matched your search

+5 -5
View File
@@ -69,7 +69,7 @@ export function publicDealOfferAction(targets: readonly string[], terms: string,
const travelKeys = travel ? Object.keys(travel).filter(key => key !== 'dueTurn').sort().join(',') : '';
const travelDeadline = travel && Object.hasOwn(travel, 'dueTurn') ? travel.dueTurn : undefined;
if (travel && (!proposer || targets.includes(proposer) ||
(groupTravel ? !!payment || travelKeys !== 'actor,answer,kind,minimum,territory' ||
(groupTravel ? !!payment && payment.kind !== 'immediateBribe' || travelKeys !== 'actor,answer,kind,minimum,territory' ||
typeof travel.actor !== 'string' || !targets.includes(travel.actor) :
travelKeys !== 'answer,kind,minimum,territory' ||
!!payment && payment.kind !== 'immediateBribe') ||
@@ -121,7 +121,7 @@ export function PublicDealList({ game, act, disabled }: {
const finalAcceptance = recipient && !accepted.includes(game.me) && accepted.length === participants.length - 1;
const travelActorWaiting = !!travel && participants.length > 2 && game.me === travelActor &&
participants.some(participant => participant !== travelActor && !accepted.includes(participant));
const paymentBlocked = payment?.kind === 'immediateBribe' && finalAcceptance ? game.bribeOptions?.blocked : null;
const paymentBlocked = payment?.kind === 'immediateBribe' && finalAcceptance && payment.payer === game.me ? game.bribeOptions?.blocked : null;
const paymentExpired = payment?.kind === 'deferredBribe' && game.turn > payment.dueTurn;
const deferredOption = (game as DeferredPaymentProjection).deferredDealPaymentOptions?.[deal.id];
const mayPay = payment?.kind === 'deferredBribe' && deal.status === 'active' && paymentStatus === 'pending' &&
@@ -227,7 +227,7 @@ export function PublicDeals({ game, act, busy }: {
...(selected.length > 1 ? {actor:travelActor} : {}),
...(travelTurn > game.turn ? {dueTurn:travelTurn} : {})} : undefined;
const combinedPaymentValid = !includeTravel || !payment || payment.kind === 'immediateBribe' &&
selected.length === 1 && paymentPeopleAndAmountValid;
paymentPeopleAndAmountValid;
const offer = legalSelection && paymentValid && (!includeTravel || travelDueValid)
? publicDealOfferAction(selected, terms, payment, me?.id, game.turn, travel) : null;
const disabled = busy || !!game.roomControl?.paused || !!game.roomControl?.closed || !!me?.autopilot;
@@ -308,8 +308,8 @@ export function PublicDeals({ game, act, busy }: {
{includeTravel && <fieldset>
<legend>Travel term</legend>
<p className="fine">This term concerns one physical action during the selected turn. The sole recipient commits to travel in a two-party deal. In a group deal, choose one recipient to commit; they accept last after all other recipients. Written terms remain player-managed.</p>
<p className="fine">A two-party travel term may include an immediate payment in either direction. The payment recipient collects their share at the next Mentat opening and can use it after collection. Group travel terms cannot include a payment.</p>
{!combinedPaymentValid && <p role="alert">For two-party travel, choose an immediate payment between the two participants. Group travel cannot include payment.</p>}
<p className="fine">A travel term may include an immediate payment between two participants. The payment recipient collects their share at the next Mentat opening and can use it after collection. All invited parties accept before the traveler gives final consent.</p>
{!combinedPaymentValid && <p role="alert">For travel, choose an immediate payment between two participants.</p>}
{selected.length > 1 && <label>Committed traveler
<select value={selected.includes(travelActor) ? travelActor : ''} disabled={disabled}
onChange={event => setTravelActor(event.target.value)}>