Support staged group shipment funding
Verify and publish checkpoint container / container (push) Canceled after 0s

This commit is contained in:
Quintine committed 2026-10-28 23:14:44 +11:00
1 parent 624f95dde4
commit 34aa64cdef
13 files changed
+828 -16

No files matched your search

+18 -3
View File
@@ -285,6 +285,7 @@ import { MoritaniAssassinate, MoritaniAssassinateHistory } from './moritani-assa
import { MoritaniExtortion, MoritaniExtortionNotice } from './moritani-extortion';
import { AdvancedAllySeparation } from './advanced-ally-separation';
import { CoalitionNexus } from './coalition-nexus';
import { CoalitionFunding, coalitionFundingContributions, type CoalitionFundingContribution } from './coalition-funding';
import { NexusEmperorPayment } from './nexus-emperor-payment';
import { NexusEmperorSellerPurchase } from './nexus-emperor-seller-purchase';
import { NexusEmperorAmbassadorPurchase } from './nexus-emperor-ambassador-purchase';
@@ -583,6 +584,7 @@ export function GameTable({
});
const [aidAmount, setAidAmount] = useState(0);
const [allyPayment, setAllyPayment] = useState('');
const [coalitionShares, setCoalitionShares] = useState<{key:string; shares:CoalitionFundingContribution[]}>({key:'', shares:[]});
const fillBattlePlan = (plan: Plan) => {
setDial(plan.dial);
setSupport(plan.support);
@@ -780,9 +782,17 @@ export function GameTable({
if (useGuildSecret && shipmentCost === null && !g.nexusGuildSecretAlly?.blocked) shipmentProblems.push('Choose a current Guild Secret Ally shipment.');
if (useRicheseShipment && shipmentCost === null && !g.nexusRichese?.blocked)
shipmentProblems.push('Choose a current Richese Secret Ally shipment of up to five physical forces.');
const coalitionFundingKey = JSON.stringify(g.coalitionFunding?.incoming.map(({donor, amount}) => [donor, amount]) ?? []);
const currentCoalitionShares = g.coalitionFunding && coalitionShares.key === coalitionFundingKey
? coalitionFundingContributions(g.coalitionFunding.incoming,
Object.fromEntries(coalitionShares.shares.map(share => [share.donor, share.amount]))) : [];
const groupShipmentShare = currentCoalitionShares.reduce((sum, share) => sum + share.amount, 0);
const availableShipmentAid = g.coalitionFunding
? g.coalitionFunding.incoming.reduce((sum, share) => sum + share.amount, 0) : g.aid.available;
const selectedAllyPayment =
shipmentCost === null
? 0
: g.coalitionFunding ? groupShipmentShare
: !me.ally || allyPayment === ''
? Math.max(0, shipmentCost - (me.spice ?? 0))
: Number(allyPayment);
@@ -797,9 +807,9 @@ export function GameTable({
`Ally payment must be a whole number from 0 to ${shipmentCost}.`,
);
else {
if (selectedAllyPayment > g.aid.available)
if (selectedAllyPayment > availableShipmentAid)
shipmentProblems.push(
`Only ${g.aid.available} pledged ally spice is available.`,
`Only ${availableShipmentAid} pledged ally spice is available.`,
);
if (shipmentCost - selectedAllyPayment > (me.spice ?? 0))
shipmentProblems.push(
@@ -4226,6 +4236,9 @@ export function GameTable({
<ChoamGamont game={g} act={act} busy={busy} />
<ChoamWorthless game={g} act={act} busy={busy} />
<ChoamBattleFunding game={g} act={act} busy={busy} />
{g.coalitionFunding && <CoalitionFunding view={g.coalitionFunding} busy={busy} act={act}
{...(shipmentAvailable ? {onContributionsChange:(shares:CoalitionFundingContribution[]) =>
setCoalitionShares({key:coalitionFundingKey, shares})} : {})} />}
{me.ally && [3, 5].includes(g.phase) && (
<details className="alliance-funding">
<summary>
@@ -4940,7 +4953,7 @@ export function GameTable({
quote={shipmentQuote}
funding={{
ownSpice: me.spice ?? 0,
pledgedSpice: g.aid.available,
pledgedSpice: availableShipmentAid,
}}
unavailableReasons={shipmentProblems}
/>
@@ -4957,6 +4970,8 @@ export function GameTable({
const shipment: Action = {
type: 'ship', elite: eliteAmount, ...payment,
territory: selected, sector, amount,
...(g.coalitionFunding && currentCoalitionShares.length
? {allyPayment: 0, coalitionContributions: currentCoalitionShares} : {}),
...(smugglerOffer ? { smuggler: useSmuggler } : {}),
...(homeworldSources ? { homeworldSources } : {}),
};