Support paid current-turn travel deals
Verify and publish checkpoint container / container (push) Successful in 10m34s

This commit is contained in:
Quintine committed 2026-10-29 07:49:56 +11:00
1 parent 82c639c977
commit a1b2aacbac
9 files changed
+371 -23

No files matched your search

+2 -2
View File
@@ -42395,7 +42395,7 @@ function applyActionWithInitiator(state: Game, id: string, action: Action, initi
if (action.type === 'dealOffer') {
const keys = Object.keys(action).sort().join(',');
const single = (keys === 'target,terms,type' || keys === 'payment,target,terms,type' ||
keys === 'target,terms,travel,type') && typeof action.target === 'string';
keys === 'target,terms,travel,type' || keys === 'payment,target,terms,travel,type') && typeof action.target === 'string';
const multiple = (keys === 'targets,terms,type' || keys === 'payment,targets,terms,type') && Array.isArray(action.targets) &&
action.targets.every(target => typeof target === 'string');
const hasPayment = Object.hasOwn(action, 'payment');
@@ -42413,7 +42413,7 @@ function applyActionWithInitiator(state: Game, id: string, action: Action, initi
? createMultipartyPublicDeal(seats, id, action.targets as string[], action.terms as string, g.turn, event, payment!)
: createMultipartyPublicDeal(seats, id, action.targets as string[], action.terms as string, g.turn, event));
if (Object.hasOwn(action, 'travel')) {
requireRule(single && !hasPayment && !g.advanced && g.expansions.length === 0 &&
requireRule(single && !g.advanced && g.expansions.length === 0 &&
nativePromiseScopeSupported(g), 'Choose a two-player travel agreement in a supported Basic table.');
offer = publicDealRule(() => setPublicDealTravel(offer, action.travel, seats));
}
+9 -7
View File
@@ -161,13 +161,14 @@ export function validatePublicDeals(value: unknown, players: readonly PublicDeal
parties = [deal.from, deal.to];
participants(players, parties);
}
if (Object.hasOwn(deal, 'travel')) {
requireDeal(!multi && !Object.hasOwn(deal, 'payment') && !Object.hasOwn(deal, 'paymentStatus'),
'A travel term requires a two-party deal without a payment term.');
parsePublicDealTravel(deal.travel);
}
const payment = Object.prototype.hasOwnProperty.call(deal, 'payment')
? parsePublicDealPayment(deal.payment, parties, deal.turn as number) : undefined;
if (Object.hasOwn(deal, 'travel')) {
requireDeal(!multi && !Object.hasOwn(deal, 'paymentStatus') &&
(!payment || payment.kind === 'immediateBribe' && payment.payer === deal.from && payment.recipient === deal.to),
'A travel term requires a two-party deal with no payment or an immediate bribe from the proposer to the recipient.');
parsePublicDealTravel(deal.travel);
}
if (payment?.kind === 'deferredBribe') {
const status = deal.paymentStatus;
requireDeal(deal.status === 'active' ? status === 'pending' || status === 'paid' || status === 'void' :
@@ -222,8 +223,9 @@ export function setPublicDealTravel(deal: PublicDeal, value: unknown, players: r
validatePublicDeals([deal], players);
requireDeal(deal.status === 'offered' && !Object.hasOwn(deal, 'participants') &&
!Object.hasOwn(deal, 'acceptVotes') && !Object.hasOwn(deal, 'travel') &&
!Object.hasOwn(deal, 'payment') && !Object.hasOwn(deal, 'paymentStatus'),
'Only a fresh two-party offer without payment can add a travel term.');
!Object.hasOwn(deal, 'paymentStatus') && (!deal.payment ||
deal.payment.kind === 'immediateBribe' && deal.payment.payer === deal.from && deal.payment.recipient === deal.to),
'Only a fresh two-party offer with no payment or an immediate proposer-to-recipient bribe can add a travel term.');
notAllied(participants(players, [deal.from, deal.to]));
const result = { ...deal, travel: parsePublicDealTravel(value) };
validatePublicDeals([result], players);