Draw a distinct Mentat Traitor replacement
replaceMoritaniAssassinationTraitors took the reserve's first entry, but the
face-up set-aside card can still sit in that list: re-drawing it produced a
receipt whose replacement equalled the revealed card, which
moritaniAssassinateIntegrity rejects mid-Mentat. The step now draws the first
distinct physical Traitor Card and is blocked with an explicit reason when none
remains, instead of committing an invalid receipt.
This is the engine half of checkpoint e493bcf, whose message described it but
whose staged path list omitted game/engine.ts. Offline suite 7,801/7,801 with
typecheck and lint clean at that revision; this commit changes no behaviour the
suite did not already exercise.
This commit is contained in:
1 parent
e493bcf58e
commit
e0101a937b
1 file changed
+6
-1
+6
-1
@@ -7799,7 +7799,12 @@ function replaceMoritaniAssassinationTraitors(g: Game) {
|
||||
requireRule(r.turn === g.turn && owner.traitors.includes(r.card!) && (g.traitorReserve?.length ?? 0) > 0,
|
||||
'Mentat replacement needs the original revealed card and one remaining physical Traitor Card.');
|
||||
owner.traitors = owner.traitors.filter(id => id !== r.card);
|
||||
r.replacement = g.traitorReserve!.shift()!;
|
||||
// The set-aside card can still sit in the reserve; the replacement must be
|
||||
// a distinct physical Traitor Card, never the revealed one again.
|
||||
const index = g.traitorReserve!.findIndex(id => id !== r.card);
|
||||
requireRule(index >= 0,
|
||||
'The Traitor Deck cannot supply a distinct replacement for the revealed Assassinate traitor.');
|
||||
r.replacement = g.traitorReserve!.splice(index, 1)[0];
|
||||
owner.traitors.push(r.replacement);
|
||||
r.stage = 'replaced';
|
||||
syncMoritaniAssassinateReceipt(g,r);
|
||||
|
||||
Reference in new issue
Block a user