Allow Sapho order behind a started turn
This commit is contained in:
1 parent
3bf7d26e80
commit
8e6602633d
17 files changed
+1121
-62
No files matched your search
@@ -10,6 +10,8 @@ import { CardInspector } from './card-inspector';
|
||||
function unavailableReason(game: GameView) {
|
||||
if (game.status !== 'playing')
|
||||
return 'Order changes are available during play.';
|
||||
if (game.phase === 5)
|
||||
return 'Movement order supports clean combined-turn boundaries and queuing behind a started active turn. The active player finishes unchanged; only later unstarted turns can be reordered. Finish pending interactions and preparations first: Sapho never splits an active combined shipment and movement turn. The Advanced Guild retains its next timing choice; an already granted current Guild turn cannot be displaced, and last remains after the Guild. A Karama-locked privilege stays locked. Completed turns and actual shipment and movement counters stay unchanged. Already-held positions and committed cards remain unavailable.';
|
||||
if (game.truthtrance || game.response || game.phaseOpening ||
|
||||
(game.decision && !(game.phase === 8 && game.decision.kind === 'moritaniExtortion')))
|
||||
return 'Finish the current interaction before changing turn order.';
|
||||
@@ -22,8 +24,6 @@ function unavailableReason(game: GameView) {
|
||||
return 'No cyclic order change is available for your pending bid. A passed player waits for a new raise; the current high bidder has no pending bid. Already-held positions and committed cards are unavailable.';
|
||||
return 'No order change is available for you in this lot. You must not have bid or passed; discarding this card can open a hand slot, but a completed opportunity cannot be repeated. A card already committed elsewhere cannot be used.';
|
||||
}
|
||||
if (game.phase === 5)
|
||||
return 'Movement order can change only before the current combined shipment and movement turn begins. First requires all remaining turns to be unstarted. The Advanced Guild retains its next timing choice; an already granted current Guild turn cannot be displaced. A Karama-locked privilege stays locked. Completed turns, already-held positions and committed cards remain unavailable.';
|
||||
if (game.phase === 6)
|
||||
return game.battle
|
||||
? game.battle.saphoTimingVersion === 1
|
||||
@@ -33,6 +33,37 @@ function unavailableReason(game: GameView) {
|
||||
return 'These controls support Once Around and cyclic bidding, movement order, remaining battle-choice order and aggressor priority. Other phase modes remain unfinished.';
|
||||
}
|
||||
|
||||
type SaphoOption = NonNullable<GameView['saphoOptions']>[number];
|
||||
|
||||
/** Submit only action fields: projected timing guidance is display metadata. */
|
||||
export function SaphoOrderButton({
|
||||
card,
|
||||
option,
|
||||
act,
|
||||
busy,
|
||||
}: {
|
||||
card: string;
|
||||
option: SaphoOption;
|
||||
act: (action: Action) => void;
|
||||
busy: boolean;
|
||||
}) {
|
||||
const bidding = option.scope === 'onceAround' || option.scope === 'cyclicAuction';
|
||||
return (
|
||||
<Button
|
||||
className="min-h-11 whitespace-normal motion-reduce:transition-none"
|
||||
disabled={busy}
|
||||
onClick={() => {
|
||||
if (!busy) act({
|
||||
type: 'card', card, scope: option.scope, event: option.event, mode: option.mode,
|
||||
});
|
||||
}}
|
||||
>
|
||||
{option.scope === 'battleAggressor' ? 'Become aggressor and discard Juice of Sapho' :
|
||||
`${bidding ? 'Bid' : option.scope === 'battleOrder' ? 'Choose battles' : option.scope === 'extortion' ? 'Take your Extortion choice' : 'Take your movement turn'} ${option.mode} and discard Juice of Sapho`}
|
||||
</Button>
|
||||
);
|
||||
}
|
||||
|
||||
export function JuiceOfSapho({
|
||||
game,
|
||||
act,
|
||||
@@ -67,11 +98,27 @@ export function JuiceOfSapho({
|
||||
const battle = option.scope === 'battleOrder';
|
||||
const aggressor = option.scope === 'battleAggressor';
|
||||
const extortion = option.scope === 'extortion';
|
||||
const afterCurrent = option.scope === 'movement' && option.afterCurrent;
|
||||
const currentPlayer = afterCurrent
|
||||
? game.players.find(player => player.id === afterCurrent)?.name ?? 'The active player'
|
||||
: null;
|
||||
return (
|
||||
<div
|
||||
key={`${option.scope}-${option.event}-${option.mode}`}
|
||||
className="flex min-w-0 flex-col gap-2"
|
||||
>
|
||||
{currentPlayer && (
|
||||
<p>
|
||||
Provisional queued movement order: {currentPlayer} finishes
|
||||
the current combined shipment and movement turn unchanged.
|
||||
Your {option.mode} position applies among later unstarted
|
||||
combined turns. Completed turns and actual shipment and
|
||||
movement counters stay unchanged.
|
||||
{game.advanced && game.players.some(player => player.faction === 'guild' && player.id !== game.me)
|
||||
? ' The Advanced Guild keeps its native timing choice at the next boundary. A last position still follows the Guild.'
|
||||
: ''}
|
||||
</p>
|
||||
)}
|
||||
<p>
|
||||
{aggressor
|
||||
? 'Become this battle’s aggressor. You win ordinary ties; a Habbanya Stronghold advantage still takes precedence. The participants, committed plans and later battle choices stay unchanged.'
|
||||
@@ -85,16 +132,7 @@ export function JuiceOfSapho({
|
||||
? `Choose your remaining battles ${option.mode}. Completed battles stay resolved. This changes who chooses next, not the aggressor or tie advantage of a battle. Other players may still choose battles against you before your turn.`
|
||||
: `Take the ${option.mode} remaining combined shipment and movement turn. Completed turns stay completed${option.mode === 'last' ? ', and the Guild cannot move behind you' : game.advanced && game.players.some(player => player.faction === 'guild' && player.id !== game.me) ? '. Provisional first priority: the Guild retains its next legal timing choice and may take its turn before yours; a Karama-locked privilege stays locked' : ''}.`}
|
||||
</p>
|
||||
<Button
|
||||
className="min-h-11 whitespace-normal motion-reduce:transition-none"
|
||||
disabled={busy}
|
||||
onClick={() => {
|
||||
if (!busy) act({ type: 'card', card: card.id, ...option });
|
||||
}}
|
||||
>
|
||||
{aggressor ? 'Become aggressor and discard Juice of Sapho' :
|
||||
`${once || cyclic ? 'Bid' : battle ? 'Choose battles' : extortion ? 'Take your Extortion choice' : 'Take your movement turn'} ${option.mode} and discard Juice of Sapho`}
|
||||
</Button>
|
||||
<SaphoOrderButton card={card.id} option={option} act={act} busy={busy} />
|
||||
</div>
|
||||
);
|
||||
})
|
||||
|
||||
Reference in new issue
Block a user