diff --git a/README.md b/README.md
index da7bb8b9..4a251f46 100644
--- a/README.md
+++ b/README.md
@@ -79,7 +79,9 @@ persists through refresh. See [Ecaz Loyalty](docs/ECAZ_LOYALTY.md).
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).
+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).
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/rihani-decipherer.tsx b/components/rihani-decipherer.tsx
index 322b066b..d1eaa798 100644
--- a/components/rihani-decipherer.tsx
+++ b/components/rihani-decipherer.tsx
@@ -13,13 +13,14 @@ function identity(game: GameView, id: string): LeaderDisplayIdentity | null {
const leader = game.allLeaders.find((l) => l.id === id);
return leader ? { id: leader.id, name: leader.name, factionName: faction(leader.faction).name, strength: leaderStrengthLabel(leader) } : null;
}
-function Card({ game, id }: { game: GameView; id: string }) {
+function Card({ game, id, faceDancer = false }: { game: GameView; id: string; faceDancer?: boolean }) {
const card = identity(game, id);
- return card ?
{card.name}
: Card identity unavailable.
;
+ return card ? {card.name}
: Card identity unavailable.
;
}
export function RihaniHistory({ game }: { game: GameView }) {
const history = game.rihani?.history;
+ const faceDancer = game.players.find(p => p.id === game.me)?.faction === 'tleilaxu';
if (!history?.length) return null;
return
Your private Rihani inspections
@@ -27,7 +28,7 @@ export function RihaniHistory({ game }: { game: GameView }) {
{[...history].reverse().map((r) =>
Turn {r.turn}
{r.peeked.length > 0 && <>
Normal inspection — returned to the shuffled deck
{r.peeked.map((id) =>
)}>}
- {r.drawn.length > 0 && <>
Separate skilled draw
{r.drawn.map((id) =>
)}>}
+ {r.drawn.length > 0 && <>
Separate skilled draw
{r.drawn.map((id) =>
)}>}
{r.kept &&
Kept {identity(game, r.kept)?.name}; revealed and returned {identity(game, r.given!)?.name}.
}
)}
;
@@ -38,24 +39,27 @@ export function RihaniChoice({ game, act, busy }: { game: GameView; act: (action
const pending = game.rihani?.pending;
if (!pending || pending.owner !== game.me) return null;
const blocked = busy || !!game.truthtrance;
+ const faceDancer = game.players.find(p => p.id === game.me)?.faction === 'tleilaxu';
+ const cardName = faceDancer ? 'Face Dancer' : 'Traitor';
+ const oldCard = faceDancer ? 'unrevealed' : 'unused';
if (pending.stage === 'offer') return
- You may draw two Traitor Cards. Once drawn, you must keep one new card by publicly revealing and returning one unused card you already hold.
+ You may draw two {cardName} Cards. Once drawn, you must keep one new card by publicly revealing and returning one {oldCard} card you already hold.
The other drawn card returns secretly. Your normal inspection, when available, has already returned its cards to the shuffled deck.
-
+
;
- return
- Keep one newly drawn card and reveal one unused card from your old hand. The revealed card and the other new card return to the shuffled deck.
-