diff --git a/README.md b/README.md index 4a251f46..0fcc1181 100644 --- a/README.md +++ b/README.md @@ -81,7 +81,9 @@ The local Leader Skills prototype also supports Basic Moritani with base opponents and the full fourteen-card deck. See [entry, connected interactions and remaining boundaries](docs/MORITANI_LEADER_SKILLS.md). Basic Tleilaxu also supports the full deck, native Rihani exchanges and saved revival choices; see -[its integration boundary](docs/TLEILAXU_LEADER_SKILLS.md). +[its integration boundary](docs/TLEILAXU_LEADER_SKILLS.md). Basic Ixians now connect +cyborg movement, HMS routes and battle aftermath through the same full deck; see +[Ixian integration](docs/IX_LEADER_SKILLS.md). Above the board, **Treachery draw pile** and **Spice draw pile** show live card counts separately from hands, auction cards and discards. See diff --git a/components/planetologist-movement.tsx b/components/planetologist-movement.tsx index e322c610..072615f1 100644 --- a/components/planetologist-movement.tsx +++ b/components/planetologist-movement.tsx @@ -5,6 +5,7 @@ import type { Action, GameView } from '@/game/engine'; import { planetologistLeader, planetologistMovementModeSupported, + selectedOriginElites, type PlanetologistMoveMode, } from '@/game/planetologist-movement'; import { botGroundMoveAllowed } from '@/game/bot-mobility'; @@ -93,7 +94,8 @@ export function planetologistMoveDraft( if ( selected.some( ([from]) => - !botGroundMoveAllowed(game, me, from, target, elites[from] ?? 0, mode), + !botGroundMoveAllowed(game, me, from, target, + selectedOriginElites(selected, elites, splitLocation(from).territory), mode), ) ) return { @@ -194,6 +196,12 @@ export function PlanetologistMovement({ Destination: {territory(destination).name}, sector {sector}. Select the physical forces to move below.

+ {me.faction === 'ixians' && ( +

+ Each origin uses its own selected cyborgs for movement range. Cyborgs + from one territory cannot carry suboids from the other territory farther. +

+ )} {sources.length ? ( sources.map(([from, owned]) => { const source = splitLocation(from); diff --git a/components/sandmaster-movement.tsx b/components/sandmaster-movement.tsx index f154dcbd..f78bd175 100644 --- a/components/sandmaster-movement.tsx +++ b/components/sandmaster-movement.tsx @@ -3,10 +3,8 @@ import { useId, useState } from 'react'; import type { Action, GameView } from '@/game/engine'; import { - GRAPH, gameTerritories, location, - mobileRouteDistance, splitLocation, } from '@/game/board'; import { @@ -17,6 +15,8 @@ import { sandmasterLeader, sandmasterModeSupported, sandmasterPathBlocked, + sandmasterAdjacent, + sandmasterRouteDistance, type SandmasterChoice, } from '@/game/sandmaster-movement'; import { Button } from './ui/button'; @@ -144,18 +144,18 @@ export function SandmasterMovement({ const extensions = last === destination ? [] - : (GRAPH[last] ?? []).filter( + : sandmasterAdjacent(game, last).filter( (next) => !route.includes(next) && !sandmasterPathBlocked(game, game.me, from, next) && - mobileRouteDistance([...route, next]) <= order.range, + sandmasterRouteDistance(game, [...route, next]) <= order.range, ); return (
{placeName(game, from)} route

{route.map((key) => placeName(game, key)).join(' → ')} ·{' '} - {mobileRouteDistance(route)} / {order.range} territories + {sandmasterRouteDistance(game, route)} / {order.range} territories