Offer Semuta on transport, Gamont and Storm conversion costs
This commit is contained in:
1 parent
06b0b354d0
commit
27959b4655
11 files changed
+1413
-2
No files matched your search
+18
-2
@@ -6071,7 +6071,7 @@ function semutaMarketGrantKaramaResponse(g: Game, response: ResponseWindow, play
|
||||
}
|
||||
}
|
||||
/** Ordinary Advanced advisor conversion sources retain their native timing:
|
||||
* preparation, uncommitted matching or an already completed ground movement. */
|
||||
* preparation, uncommitted matching or an already completed native producer. */
|
||||
function semutaAdvisorFlipKaramaResponse(g: Game, response: ResponseWindow, player: string): boolean {
|
||||
if (response.kind !== 'advisorFlip' || !g.advanced ||
|
||||
response.owner !== byFaction(g,'beneGesserit')?.id ||
|
||||
@@ -6089,7 +6089,7 @@ function semutaAdvisorFlipKaramaResponse(g: Game, response: ResponseWindow, play
|
||||
(!!g.pendingAutomaticAdvisorFlips?.length !== !!response.automaticAdvisorFlip)) return false;
|
||||
if ((g.auction || g.richeseAuction) && !response.advisorPreparationSource) return false;
|
||||
if (response.automaticAdvisorFlip &&
|
||||
g.pendingAutomaticAdvisorFlips?.some(source => source.producer !== 'groundMovement')) return false;
|
||||
g.pendingAutomaticAdvisorFlips?.some(source => !['groundMovement','guildTransport','gamont','storm'].includes(source.producer))) return false;
|
||||
const context: Game = {...g,pendingTreacheryDiscard:null,response};
|
||||
try {
|
||||
// Native source quotes validate denial without requiring the spent card,
|
||||
@@ -6125,6 +6125,7 @@ function karamaResponseDiscardSignature(g: Game, c: KaramaResponseDiscardContinu
|
||||
const e3 = c.kind === 'karamaEcazMoritaniDiscard';
|
||||
const marketGrant = c.kind === 'karamaMarketDiscard' || c.kind === 'karamaFremenGrantDiscard';
|
||||
const advisor = c.kind === 'karamaAdvisorFlipDiscard';
|
||||
const advisorProducer = advisor ? c.use.response.automaticAdvisorFlip?.producer : undefined;
|
||||
return JSON.stringify({
|
||||
player: c.player, card: c.card, use: c.use,
|
||||
parent: nullentropyParentSignature(g, c.resume,
|
||||
@@ -6339,6 +6340,21 @@ function karamaResponseDiscardSignature(g: Game, c: KaramaResponseDiscardContinu
|
||||
noField:p.noField, noFieldEvent:p.noFieldEvent, flipBlocked:p.advisorFlipMovementBlocked,
|
||||
hajr:p.hajrPlays, window:p.hajrWindow, leaders:p.leaders, kwisatz:p.kwisatz})),
|
||||
} : undefined,
|
||||
advisorParent: advisorProducer === 'guildTransport' ? {
|
||||
transport:g.pendingAutomaticAdvisorTransport, pending:g.pendingGuildTransport,
|
||||
rate:g.guildRateBlocked, permission:g.guildTransportBlocked,
|
||||
price:g.karamaShipping, homeworlds:g.homeworlds,
|
||||
} : advisorProducer === 'gamont' ? {
|
||||
gamont:g.pendingAutomaticAdvisorGamont, worthless:g.pendingChoamWorthless,
|
||||
mentat:g.choamMentatPending, market:g.choamMarket,
|
||||
cleanup:g.moritaniTerror, order:g.order, spice:g.spice,
|
||||
} : advisorProducer === 'storm' ? {
|
||||
storm:g.pendingAutomaticAdvisorStorm, sector:g.storm, pending:g.stormPending,
|
||||
cursor:g.stormResolution, source:g.stormMovementSource,
|
||||
dials:g.stormDials, dialers:g.stormDialers, card:g.stormCard, known:g.stormCardKnown,
|
||||
spice:g.spice, wall:g.shieldWallDestroyed,
|
||||
ecological:g.ecologicalStorm, maker:g.greatMaker,
|
||||
} : undefined,
|
||||
order: g.order,
|
||||
players: g.players.map(p => ({
|
||||
id: p.id, faction: p.faction, ally: p.ally,
|
||||
|
||||
@@ -1298,6 +1298,7 @@ export const RULE_TOPICS: RuleTopic[] = [
|
||||
'Karama stopping native Ecaz or Moritani placement, Moritani’s earned Duke acquisition, Ecaz Occupy or Enemy of My Enemy also offers its used cost. Claim or Continue keeps earlier payments, physical tokens, the selected battle lead and paid entry intact, then applies the original denial once. Moritani may still reveal or decline its Terror token. Ecaz’s shared-stronghold Collection bonus is Advanced-only: a restricted fresh development setup offers this cost before ordinary collection settles, withholding only the canceled bonus. Basic collection has no such bonus; public Advanced Semuta starts and wider combinations remain guarded.',
|
||||
'Karama stopping a native CHOAM sale, Richese Black Market, Ixian ally replacement or Fremen allied free-revival grant also offers its fresh used cost. Claim or Continue applies the original denial once: a canceled sale keeps its unsold card and earns nothing; Black Market returns through its unbid continuation; replacement keeps the original paid card and skips the exchange; the ally retains intrinsic revival rates and completed returns. Allowance still uses the original sale, auction, draw or grant controls. Only the used Treachery cost is fresh at this response.',
|
||||
'Advanced advisor preparation, ordinary incoming-group matching and mandatory conversion after a ground move also offer the used Karama cost. Claim or Continue preserves the original auction or movement boundary, applies only native conversion denial and resumes once. Matching keeps the uncommitted groups and unused move; a completed departure keeps its transferred forces and queued arrival. The existing continuously-alone hold is provisional. Other advisor producers and broader parents remain unfinished.',
|
||||
'Mandatory advisor conversions after committed Guild cross-shipment or reserve return, Trip to Gamont and a Storm sector also offer the exact used Karama cost. Claim or Continue retains the original payment, transferred or returned counters, used fuel and completed casualties. The original parent then resumes its arrival, Mentat choice or remaining Storm traversal once. Denial preserves the existing continuously-alone hold while its physical occurrence survives; it does not reverse the producer or stop later Storm casualties.',
|
||||
'Printed-role Karama stopping ordinary Basic Spiritual Advisors, Atreides Movement foresight, Advanced Fremen Storm knowledge or native Face Dancer replacement also offers its exact used cost. Claim or Continue finishes that original prevention once. The paid shipment and remaining turn stay intact; the stopped free packet is not placed. Foresight gains no new knowledge or draw. An original Bene Gesserit stance or Guild opening choice waits unchanged until the Atreides cost finishes. A stopped replacement retains the original Face Dancers and reserve, with its attempt still used. Storm opening acknowledgements must finish before cancellation; they are never bypassed or repeated. Complex Spiritual and arrival parents remain separate.',
|
||||
'Printed-role Karama stopping ordinary native Fremen range, Cyborg range, Advanced Guild timing or HMS movement/collection also offers its exact used cost. Claim or Continue completes the original denial once. Fremen and Ixian forces remain in place with their move unused and current-use restriction intact; choose a legal replacement. Guild follows the original remaining queue under its native timing lock. A canceled HMS route neither relocates nor collects; only after the fresh cost finishes does the original Storm turn begin, including its normal Advanced card handling. No declaration, payment, movement, collection or turn opening repeats. Card-flight and other complex parents retain their separate boundaries.',
|
||||
'The explicit fresh Leader Skills entry composes Semuta with original all-fourteen-card native Basic Richese/CHOAM or Advanced E1/E2 setup, retaining original Tech and Advanced Stronghold prerequisites. Actual offers train original living discs; the native Auditor remains ineligible. A completed Hajr discard can resume the same Movement owner before an original private Mentat question. Mandatory loser disposal can resume trained Suk casualty rescue or Rihani’s normal private inspection and optional skilled exchange before winner cleanup. Winning compulsory Artillery stays held through the original skill, then becomes its own fresh Treachery discard. Traitor/Face Dancer movement is never a Semuta target; no rescue, question, inspection or exchange repeats. Basic Ix mixtures, E3, other module/Banker overlays and public starts stay separate.',
|
||||
@@ -1476,6 +1477,12 @@ export const RULE_TOPICS: RuleTopic[] = [
|
||||
'tests/semuta-advisor-matching-engine.test.ts',
|
||||
'tests/fixture-semuta-advisor-alone.ts',
|
||||
'tests/semuta-advisor-alone-engine.test.ts',
|
||||
'tests/fixture-semuta-advisor-transport.ts',
|
||||
'tests/semuta-advisor-transport-engine.test.ts',
|
||||
'tests/fixture-semuta-advisor-gamont.ts',
|
||||
'tests/semuta-advisor-gamont-engine.test.ts',
|
||||
'tests/fixture-semuta-advisor-storm.ts',
|
||||
'tests/semuta-advisor-storm-engine.test.ts',
|
||||
'tests/fixture-semuta-spiritual-foresight.ts',
|
||||
'tests/semuta-spiritual-foresight-engine.test.ts',
|
||||
'tests/fixture-semuta-storm-dancer.ts',
|
||||
|
||||
Reference in new issue
Block a user