Connect bounded arrival overlap and Fremen Nexus movement Betrayal
This commit is contained in:
1 parent
8ddd138e87
commit
b2603f6715
26 files changed
+1644
-118
No files matched your search
@@ -33,6 +33,7 @@ import { NexusChoamBetrayal } from './nexus-choam-betrayal';
|
||||
import { NexusMoritaniBetrayal } from './nexus-moritani-betrayal';
|
||||
import { buildRevision, buildRevisionLabel } from '@/lib/build-revision';
|
||||
import { NexusEcazBetrayal } from './nexus-ecaz-betrayal';
|
||||
import { NexusFremenBetrayal } from './nexus-fremen-betrayal';
|
||||
import { NexusEcazInquiry } from './nexus-ecaz-inquiry';
|
||||
import { NexusEcazDuke } from './nexus-ecaz-duke';
|
||||
import { NexusTleilaxu } from './nexus-tleilaxu';
|
||||
@@ -1050,6 +1051,18 @@ export function GameTable({
|
||||
<EcazLoyaltyCard loyalty={g.ecazLoyalty} />
|
||||
<MoritaniTerrorSupply game={g} />
|
||||
<MoritaniExtortionNotice game={g} />
|
||||
{g.arrivalOverlap && (
|
||||
<section className="notice" aria-label="Ambassador and Terror response order">
|
||||
<p>
|
||||
{g.players.find((player) => player.id === g.arrivalOverlap!.entrant)?.name ?? 'The entrant'}
|
||||
{' '}entered {territory(g.arrivalOverlap.territory).name}. Ecaz Ambassador
|
||||
and Moritani Terror resolve in storm order:{' '}
|
||||
{g.arrivalOverlap.first === 'ambassador' ? 'Ecaz, then Moritani' : 'Moritani, then Ecaz'}.
|
||||
{' '}{g.arrivalOverlap.active === 'ambassador' ? 'Ecaz' : 'Moritani'} decides now;
|
||||
the original entry is not repeated.
|
||||
</p>
|
||||
</section>
|
||||
)}
|
||||
<MoritaniAssassinateHistory game={g} />
|
||||
<AmbassadorSupply game={g} />
|
||||
<AmbassadorInsights key={`${g.code}-${g.me}`} game={g} />
|
||||
@@ -1607,6 +1620,7 @@ export function GameTable({
|
||||
<NexusChoamBetrayal game={g} act={act} busy={transportBusy || !!g.roomControl?.paused || !!g.roomControl?.closed || !!me.autopilot} />
|
||||
<NexusMoritaniBetrayal game={g} act={act} busy={transportBusy || !!g.roomControl?.paused || !!g.roomControl?.closed || !!me.autopilot} />
|
||||
<NexusEcazBetrayal game={g} act={act} busy={transportBusy || !!g.roomControl?.paused || !!g.roomControl?.closed || !!me.autopilot} />
|
||||
<NexusFremenBetrayal game={g} act={act} busy={transportBusy || !!g.roomControl?.paused || !!g.roomControl?.closed || !!me.autopilot} />
|
||||
<NexusEcazInquiry game={g} act={act} busy={transportBusy || !!g.roomControl?.paused || !!g.roomControl?.closed || !!me.autopilot} />
|
||||
<NexusEcazDuke game={g} act={act} busy={busy} />
|
||||
<NexusTleilaxu game={g} act={act} busy={transportBusy || (!!g.roomControl?.paused || !!g.roomControl?.closed) || !!me.autopilot} />
|
||||
@@ -4044,10 +4058,9 @@ export function GameTable({
|
||||
me.faction === 'fremen' &&
|
||||
me.fremenMovementBlocked && (
|
||||
<p className="notice">
|
||||
Karama limited this move to one territory. Your forces have
|
||||
not moved yet. Available ornithopters still allow their
|
||||
normal range; a later extra move can use your two-territory
|
||||
advantage again.
|
||||
{me.fremenNexusMovementBlocked
|
||||
? 'Fremen Nexus Betrayal suppresses your two-territory movement advantage for this turn. Available ornithopters still use their normal range.'
|
||||
: 'Karama limited this move to one territory. Your forces have not moved yet. Available ornithopters still allow their normal range; a later extra move can use your two-territory advantage again.'}
|
||||
</p>
|
||||
)}
|
||||
{g.phase === 5 && me.faction === 'ixians' && (
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
'use client';
|
||||
|
||||
import type { Action, GameView } from '@/game/engine';
|
||||
import { nexusCardReference } from '@/game/nexus-card-reference';
|
||||
import { fremenBetrayalAction } from '@/game/nexus-fremen-betrayal-options';
|
||||
import { Button } from './ui/button';
|
||||
|
||||
type Props = { game: GameView; act: (action: Action) => void; busy: boolean };
|
||||
|
||||
export function NexusFremenBetrayal({ game, act, busy }: Props) {
|
||||
const offer = game.nexusFremenBetrayal;
|
||||
if (!offer || game.nexusCards?.card !== 'fremen') return null;
|
||||
const action = fremenBetrayalAction(game);
|
||||
const fremen = game.players.find(player => player.id === offer.target);
|
||||
return (
|
||||
<section aria-label="Fremen Nexus Betrayal" className="space-y-3 rounded-lg border border-[#a88b60]/50 p-3">
|
||||
<h3>Fremen Nexus · Betrayal</h3>
|
||||
<p>{nexusCardReference('fremen').betrayal}</p>
|
||||
{fremen && <p className="fine">This bounded use suppresses {fremen.name}’s native two-territory movement advantage for the rest of this turn. Independent ornithopters remain available. Suppressing worm riding is not yet connected.</p>}
|
||||
{offer.blocked && <p className="notice">{offer.blocked}</p>}
|
||||
<Button className="game-action min-h-11 whitespace-normal" disabled={busy || !action}
|
||||
onClick={() => { if (!busy && action) act(action); }}>
|
||||
Use Betrayal: suppress Fremen movement range
|
||||
</Button>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
@@ -57,7 +57,7 @@ export function OrnithopterMovement({
|
||||
if (Object.entries(selectedForces).some(([from, count]) => count > 0 &&
|
||||
!botGroundMoveAllowed(game, me, from,
|
||||
location(String(move.territory), Number(move.sector)), 0)))
|
||||
reason = 'Karama removed this group’s two-territory advantage. Choose a reachable destination within the remaining normal range.';
|
||||
reason = 'The Fremen two-territory advantage is unavailable. Choose a reachable destination within the remaining normal range.';
|
||||
}
|
||||
const physicalSource =
|
||||
typeof move?.from === 'string'
|
||||
|
||||
Reference in new issue
Block a user