'use client'; import { useState } from 'react'; import type { Action, GameView } from '@/game/engine'; import { specialForceName } from '@/game/combat'; import { homeworldName, homeworldShipmentChoice, type HomeworldShipmentSources, } from '@/game/homeworld-shipment-options'; import { Button } from './ui/button'; import { Input } from './ui/input'; export function HomeworldShipment({ game: g, act, busy, }: { game: GameView; act: (action: Action) => void; busy: boolean; }) { const worlds = g.homeworlds?.worlds ?? []; const me = g.players.find((player) => player.id === g.me)!; const available = worlds.filter((world) => { const force = world.forces[g.me]; return force && force.normal + force.elite > 0; }); const targets = worlds.filter( (world) => (world.native !== g.me || me.faction === 'guild') && !(g.guildTransportCanceled && me.faction === 'guild' && world.native === me.id) && world.native !== me.ally, ); const [origin, setOrigin] = useState(available[0]?.id ?? ''); const [destination, setDestination] = useState( targets.find((world) => world.id !== available[0]?.id)?.id ?? '', ); const [sources, setSources] = useState({}); const [allyPayment, setAllyPayment] = useState(0); const [nexusEvent, setNexusEvent] = useState(''); const useNexus = g.karamaShipping?.player !== g.me && !!g.nexusGuildSecretAlly && nexusEvent === g.nexusGuildSecretAlly.event; const option = g.homeworldShipment; if (!option) return null; const imperial = g.advanced && me.faction === 'emperor'; const selectedOrigins = available.filter((world) => origin === 'imperial-pair' ? world.native === me.id : world.id === origin, ); const selected = Object.fromEntries( selectedOrigins.flatMap((world) => { const choice = sources[world.id]; return choice && choice.normal + choice.elite !== 0 ? [[world.id, choice]] : []; }), ); const quote = homeworldShipmentChoice( g, destination, selected, allyPayment, useNexus ? nexusEvent : undefined, ); const special = specialForceName(me.faction); return (
Ship to another Homeworld

Use your shipment to send forces from one Homeworld to another. Native reserves and foreign garrisons have separate source pools.{' '} {me.faction === 'guild' ? g.guildTransportCanceled ? 'The native Guild return permission is canceled: Junction cannot be a destination, even with a purchased price.' : 'Guild may also return a foreign garrison to Junction.' : 'Your own Homeworld cannot be a destination.'}{' '} Allied Homeworlds cannot be destinations.

{useNexus ? 'Selected Guild Nexus price: one spice per two forces, rounded up.' : g.karamaShipping?.player === g.me ? 'Purchased Karama price: one spice per two forces, rounded up, paid entirely to the bank even if the native Guild rate is canceled.' : me.faction === 'guild' ? g.guildRateCanceled ? 'The native Guild rate is canceled: pay one spice per force.' : 'Guild pays one spice per two forces, rounded up.' : 'Pay one spice per force.'}{' '} This uses your shipment; your normal movement remains available.

{g.nexusGuildSecretAlly && (

Spend the Nexus for its independent price of one spice per two forces, rounded up; it does not stack with a purchased Karama price. Existing source and destination restrictions still apply.

{g.nexusGuildSecretAlly.blocked && (

{g.nexusGuildSecretAlly.blocked}

)}
)} {option.blocked && ( {option.blocked} )}
{selectedOrigins.map((world) => { const pool = world.forces[me.id]; const chosen = sources[world.id] ?? { normal: 0, elite: 0 }; return (
{homeworldName(g, world.id)} ·{' '} {world.native === me.id ? 'native reserves' : 'foreign garrison'}

Available: {pool.normal} normal {pool.elite > 0 ? ` + ${pool.elite} ${special}` : ''}.

{(['normal', 'elite'] as const) .filter((kind) => kind === 'normal' || pool.elite > 0) .map((kind) => ( ))}
); })} {me.ally && ( )}

Your available spice: {me.spice ?? 0}. Allied pledge:{' '} {g.aid.available}.

{quote.amount} forces · {quote.cost} spice total {quote.amount > 0 ? ` · you pay ${quote.ownPayment}, ally pays ${quote.allyPayment}` : ''} .{quote.blocked && ` ${quote.blocked}`}
); }