Support staged group Guild transport
Verify and publish checkpoint container / container (push) Successful in 12m5s

This commit is contained in:
Quintine committed 2026-10-28 23:52:21 +11:00
1 parent 478b38f5de
commit 2fe97ddd1f
10 files changed
+424 -23

No files matched your search

+22 -4
View File
@@ -3,7 +3,7 @@ import { nexusGuildSecretAllyCanAct } from './nexus-guild-secret-ally-options';
import type { Action, GameView } from './engine';
import { splitLocation, validGameLocation } from './board';
import { botEntryAllowed, guildTransportCost } from './bot-mobility';
import { shipmentPaymentBounds } from './shipment-price';
import { groupGuildShipmentRate, shipmentPaymentBounds } from './shipment-price';
import { quoteAdvisorTransportMatching, AdvisorTransportMatchingError } from './advisor-transport-matching';
import { guildNoFieldSelection } from './guild-no-field-selection';
import { isBoardNoFieldLocation } from './richese-no-field';
@@ -176,6 +176,7 @@ export function guildTransportQuote(g: GameView, action: Action) {
!(
nexusAllowed ||
p.faction === 'guild' ||
!!g.coalitionFunding && groupGuildShipmentRate(g.players, p.id, g.coalitionState) ||
g.players.some((seat) => seat.id === p.ally && seat.faction === 'guild')
)
)
@@ -192,15 +193,32 @@ export function guildTransportQuote(g: GameView, action: Action) {
)
: null;
const ownSpice = p.spice ?? 0;
const pledgedSpice = g.aid.available;
const groupShares = action.coalitionContributions;
const incoming = g.coalitionFunding?.incoming ?? [];
const pledgedSpice = groupShares === undefined ? g.aid.available : incoming.reduce((sum, entry) => sum + entry.amount, 0);
const { minimum } = shipmentPaymentBounds(cost ?? 0, ownSpice, pledgedSpice);
const share = action.allyPayment ?? minimum;
let groupShareValid = groupShares === undefined;
let groupShareTotal = 0;
if (groupShares !== undefined && Array.isArray(groupShares) && g.coalitionFunding) {
const seen = new Set<string>();
groupShareValid = groupShares.every((entry: unknown) => {
if (!entry || typeof entry !== 'object' || Array.isArray(entry)) return false;
const share = entry as {donor?: unknown; amount?: unknown};
const pledged = incoming.find(item => item.donor === share.donor);
if (typeof share.donor !== 'string' || seen.has(share.donor) || !pledged ||
typeof share.amount !== 'number' || !Number.isSafeInteger(share.amount) ||
share.amount <= 0 || share.amount > pledged.amount) return false;
seen.add(share.donor); groupShareTotal += share.amount; return Number.isSafeInteger(groupShareTotal);
});
}
const share = groupShares === undefined ? action.allyPayment ?? minimum : groupShareTotal;
const validShare =
cost !== null &&
typeof share === 'number' &&
Number.isSafeInteger(share) &&
share >= 0 &&
share <= cost;
share <= cost && groupShareValid && (groupShares === undefined || !nexus && !namesNoField &&
(action.allyPayment === undefined || action.allyPayment === 0));
if (cost !== null) {
if (!validShare)
unavailableReasons.push(