Compose standalone E3 Leader Skills with Tech and Strongholds

This commit is contained in:
Quintine committed 2026-10-04 11:41:13 +11:00
1 parent a8f5a3c953
commit 2b72021611
17 files changed
+1303 -23

No files matched your search

+4 -2
View File
@@ -7531,8 +7531,10 @@ function moritaniAssassinateModeSupported(g: Game) {
g.players.some(p => p.faction === 'moritani') &&
g.players.every(p => ['moritani','atreides','beneGesserit','guild','emperor','fremen'].includes(p.faction)) &&
!g.nexusCards && (!g.leaderSkills || advancedMoritaniLeaderSkillsProfile(g)) &&
(!g.strongholdCards || e3StrongholdFactionProfile(g)) && !g.homeworlds &&
!g.discoveryEnabled && !g.discoveries && !g.techTokens;
(!g.strongholdCards || e3StrongholdFactionProfile(g) ||
(!!g.leaderSkills && strongholdLeaderSkillsProfile(g))) && !g.homeworlds &&
!g.discoveryEnabled && !g.discoveries &&
(!g.techTokens || (!!g.leaderSkills && nativeTechLeaderSkillsProfile(g)));
}
function moritaniAssassinateContext(g: Game, receipt: MoritaniAssassinateReceipt) {
const p = getPlayer(g,receipt.owner), opponent = getPlayer(g,receipt.opponent);
+24 -6
View File
@@ -50,6 +50,23 @@ function nativeLeaderSkillModulesSupported(game: LeaderSkillProfile): boolean {
return true;
}
/** Standalone E3 native predicates retain their own roster, Duke and assassination limits. */
function e3LeaderSkillModulesSupported(game: LeaderSkillProfile): boolean {
if (noOtherLeaderSkillModules(game)) return true;
const players = game.players;
if ((!game.techTokens && !game.strongholdCards) || !players ||
players.length < (game.techTokens ? 3 : 2) || players.length > 6 ||
(game.strongholdCards && game.advanced !== true) ||
game.homeworlds || game.nexusCards || game.discoveries || game.discoveryEnabled ||
game.ecazTreachery || game.semutaPreview || game.advancedPreview ||
game.kullPreview || game.nexusKullPreview || game.guildBetrayalPreview ||
game.richeseBetrayalPreview || game.nexusIxianReplacementPreview ||
game.nexusIxianBetrayalPreview || game.nexusHarkonnenBetrayalPreview) return false;
for (let i = 0; i < players.length; i++)
for (let j = 0; j < i; j++) if (players[j].faction === players[i].faction) return false;
return true;
}
/** Classic three-to-six-seat Skills/Tech composition; native and other modules stay separate. */
export function classicTechLeaderSkillsProfile(game: LeaderSkillProfile): boolean {
const players = game.players;
@@ -71,10 +88,11 @@ export function classicTechLeaderSkillsProfile(game: LeaderSkillProfile): boolea
return true;
}
/** Original Advanced Strongholds, with optional Tech, for classic or supported E1/E2 skills. */
/** Original Advanced Strongholds, with optional Tech, for classic or supported native skills. */
export function strongholdLeaderSkillsProfile(game: LeaderSkillProfile): boolean {
if (!game.strongholdCards || game.advanced !== true) return false;
if (game.expansions.length) return advancedNativeLeaderSkillsProfile(game);
if (game.expansions.length) return advancedNativeLeaderSkillsProfile(game) ||
advancedMoritaniLeaderSkillsProfile(game) || nativeEcazLeaderSkillsProfile(game);
const players = game.players;
if (!players || players.length < (game.techTokens ? 3 : 2) || players.length > 6 ||
game.homeworlds || game.nexusCards || game.discoveries || game.discoveryEnabled ||
@@ -96,7 +114,7 @@ export function strongholdLeaderSkillsProfile(game: LeaderSkillProfile): boolean
/** Bounded integration of the ordinary Moritani roster, not Advanced assassination. */
export function basicMoritaniLeaderSkillsProfile(game: LeaderSkillProfile): boolean {
return game.advanced === false && game.expansions.length === 1 &&
game.expansions[0] === 'ecaz' && noOtherLeaderSkillModules(game) &&
game.expansions[0] === 'ecaz' && e3LeaderSkillModulesSupported(game) &&
!!game.players?.some(player => player.faction === 'moritani') &&
game.players.every(player => player.faction === 'moritani' ||
FACTIONS.some(faction => faction.id === player.faction && faction.expansion === 'base'));
@@ -107,7 +125,7 @@ export function advancedMoritaniLeaderSkillsProfile(game: LeaderSkillProfile): b
const players = game.players;
if (game.advanced !== true || game.expansions.length !== 1 ||
game.expansions[0] !== 'ecaz' || !players || players.length < 2 || players.length > 6 ||
!noOtherLeaderSkillModules(game) || game.semutaPreview || game.advancedPreview ||
!e3LeaderSkillModulesSupported(game) || game.semutaPreview || game.advancedPreview ||
game.kullPreview || game.nexusKullPreview || game.guildBetrayalPreview ||
game.richeseBetrayalPreview || game.nexusIxianReplacementPreview ||
game.nexusIxianBetrayalPreview || game.nexusHarkonnenBetrayalPreview) return false;
@@ -132,7 +150,7 @@ export function nativeEcazLeaderSkillsProfile(game: LeaderSkillProfile): boolean
const players = game.players;
if (typeof game.advanced !== 'boolean' || game.expansions.length !== 1 ||
game.expansions[0] !== 'ecaz' || !players || players.length < 2 || players.length > 6 ||
!noOtherLeaderSkillModules(game) || game.semutaPreview || game.moritaniAssassinatePreview ||
!e3LeaderSkillModulesSupported(game) || game.semutaPreview || game.moritaniAssassinatePreview ||
game.advancedPreview || game.kullPreview || game.nexusKullPreview ||
game.guildBetrayalPreview || game.richeseBetrayalPreview ||
game.nexusIxianReplacementPreview || game.nexusIxianBetrayalPreview ||
@@ -248,7 +266,7 @@ export function nativeExpansionLeaderSkillsProfile(game: LeaderSkillProfile): bo
advancedMoritaniLeaderSkillsProfile(game) || nativeEcazLeaderSkillsProfile(game);
}
/** Only the original eligible E1/E2 native families gain the Tech combination. */
/** Only the original eligible native skill families gain the Tech combination. */
export function nativeTechLeaderSkillsProfile(game: LeaderSkillProfile): boolean {
return !!game.techTokens && nativeExpansionLeaderSkillsProfile(game);
}
+10 -5
View File
@@ -3181,6 +3181,7 @@ export const RULE_TOPICS: RuleTopic[] = [
'Arrakeen pays only for actual support and creates no personal cash. CHOAM force-payment income includes the bank contribution, subject to its normal traitor and donor exclusions. Carthag does not protect an empty or Worthless defense, stop Poison Tooth, or remove a Shield’s Lasgun explosion risk.',
'Sietch Tabr uses the opposing dial, excluding leaders and other bonuses. A single traitor victory qualifies; mutual destruction does not. Tuek pays after an ordinary loss or a single traitor outcome as well as a win; a double traitor gives neither faction spice. Habbanya also decides a tied Stone Burner comparison.',
'Fresh Advanced local development tables may combine all fourteen Leader Skills with Stronghold Cards in classic or supported Ixian, Tleilaxu, CHOAM and Richese skill rosters, two through six players; optional Tech Tokens needs three through six. Original deck/cache and end-Mentat claims remain. Arrakeen pays bank support, not personal income; only the remaining actual payer debit qualifies separate normal Banker income. Skill rescue preserves the original support charge, then card cleanup and Tech reward finish before Face Dance. Modified/copied Diplomat defenses and active skill/Stone interpretations stay guarded; public activation, E3/other overlays and save conversion remain separate.',
'The original standalone Ecaz or Moritani skill roster additionally supports these Advanced combinations with the exact ecaz deck, original five-disc training and native exclusions. Normal Warmaster one on a temporary Duke composes Carthag Shield without granting trained three; normal winner Suk precedes unused-disc Moritani assassination, printed bounty, retained winner Tech and one private Mentat replacement. E3 pairs, mixtures and allied Occupy skills stay separate.',
'The six effects, public ownership and pre-plan choice are integrated in development games. Enable Stronghold Cards in an Advanced preview lobby. Complete Advanced compliance and every expansion interaction remain under verification.',
],
example:
@@ -3198,7 +3199,7 @@ export const RULE_TOPICS: RuleTopic[] = [
area: 'Implementation',
status: 'Partial',
detail:
'All six local effects and end-Mentat custody are integrated. Fresh Advanced classic/supported E1/E2 skill rosters additionally compose all14 skills and optional original Tech, preserving subsidy, typed rescue, native income and reward order. Full optional-module combinations remain open.',
'All six local effects/end-Mentat custody are integrated. Fresh Advanced classic/supported native skill rosters, including standalone Ecaz/Moritani, compose all14 skills and optional original Tech. Original subsidy, physical rescue, native income/Duke/assassination and reward order remain; full combinations stay open.',
evidence: [
'game/stronghold-cards.ts',
'game/stronghold-battle.ts',
@@ -3233,12 +3234,14 @@ export const RULE_TOPICS: RuleTopic[] = [
area: 'Verification',
status: 'Partial',
detail:
'Dated standalone cases remain. Skills/Stronghold adds21 meaningful cases,277 affected and72 final fixture-consumer cases, types/lint/build, twelve actual programs and22 genuine paired/triple games (6672 actions/no rejection,171 JSON continuations). Human390px real subsidy/Banker/Mentat and HMS copied support/typed Suk/Tech preserve original outcomes on refresh. Full/deployed acceptance remains unfinished.',
'Dated standalone and E1/E2 Skills/Stronghold cases remain. Standalone E3 adds15 meaningful cases,152 affected, types/lint/build, nine actual programs and eight E3 games (1531 actions/no rejection,38 JSON continuations); the expanded47-game batch completes13936 actions/358 continuations. Human390px normal Duke/Carthag poison survival and Guild Suk before unused-disc assassination preserve original cards/Tech/income/replacement on refresh. Full/deployed acceptance remains unfinished.',
evidence: [
'tests/stronghold-cards.test.ts',
'tests/stronghold-engine.test.ts',
'tests/classic-skills-stronghold-runtime.test.ts',
'tests/native-skills-stronghold-runtime.test.ts',
'tests/ecaz-skills-modules-runtime.test.ts',
'tests/moritani-skills-modules-runtime.test.ts',
],
},
],
@@ -4495,6 +4498,7 @@ export const RULE_TOPICS: RuleTopic[] = [
'Original paid Ambassador placement and entrant reactions keep the exact token, training and movement suffix. Emperor Ambassador grants five bank spice; it is income, not a qualifying bank payment from another player for Banker.',
'A temporarily acquired Duke has printed strength six. A different living face-up Warmaster may give him only the normal one-point bonus with a physical Worthless card, never the trained-disc three. Surviving release or actual Duke death leaves the native trainer and card intact; bounty remains printed six.',
'Ecaz-only paid five-spice Duke revival retains the same living set-aside disc under the earlier selected interpretation. These paths keep an existing native skill and do not authorize shared-Duke assignment. Advanced Harkonnen, combined Occupy skills and other module/ruling boundaries remain explicit.',
'Fresh standalone Ecaz skill tables may preserve original Tech Tokens in Basic/Advanced with three through six seats, and Stronghold Cards in Advanced with two through six, optionally both. Original five-disc training, Ambassador/Duke acquisition, local held-card protection or income, Suk rescue and mandatory winner Tech remain. A native face-up Warmaster gives temporary Duke only normal one; Carthag physical Shield can prevent poison. Original paid five-spice Duke revival remains living and set aside, not reassigned. Advanced Harkonnen, allied Occupy skills, pairs, mixtures and other guards stay unchanged.',
],
related: ['leader-skills', 'duke-vidal', 'ecaz-ambassadors', 'spice-banker-income', 'implementation-checklist'],
checklist: [
@@ -4541,6 +4545,7 @@ export const RULE_TOPICS: RuleTopic[] = [
'Connected movement, shipping, payment and battle skills use the same controls and legal quotes as the base profile. Terror Assassination returns a killed leader’s exact skill once; a later own-leader revival offers the normal private optional replacement. Sabotage affects Treachery Cards, not skills.',
'An Enemy of My Enemy alliance preserves each faction’s assignments. A losing ally cannot retain a used Planetologist Special or the Worthless card used for a Diplomat copy, because those cards must be discarded.',
'Basic Moritani with base opponents keeps its existing entry, including Harkonnen. Fresh Advanced Moritani plus classic opponents except Harkonnen uses the ecaz deck and the original assassination preview with all fourteen skills. Winner Suk rescue and Rihani choice finish before post-loss assassination, without replaying casualties. The actual winning disc remains excluded; another eligible trained disc returns its skill once and pays only printed bounty. Normal traitor revelation forfeits assassination for the whole game. Ecaz/Duke skill assignment, other native families, optional modules and public starts remain separate.',
'The original standalone skill profile may additionally preserve Tech Tokens in Basic/Advanced three-through-six-seat tables and Stronghold Cards in Advanced two-through-six, optionally both. Actual normal winner Suk rescue finishes before unused trained-disc assassination and printed bounty; original winner cards/Tech, losing Tuek earnings, support and one real Mentat replacement remain. Ordinary Collection is separate. E3 pairs, mixtures, allied Occupy skills and other overlays remain guarded; public starts and save conversion stay excluded.',
],
related: ['leader-skills', 'expansion-faction-games', 'implementation-checklist'],
checklist: [
@@ -4592,8 +4597,8 @@ export const RULE_TOPICS: RuleTopic[] = [
steps: [
'Basic Moritani retains base opponents including Harkonnen. Its separate bounded Advanced classic/non-Harkonnen roster now composes the original assassination preview and all fourteen skills: winner Suk rescue and Rihani choice finish first, then an eligible different trained disc may be assassinated with its exact card return and printed bounty. No casualties repeat; original set-aside and one private Mentat replacement remain. See Moritani with Leader Skills for the exact scope.',
'Fresh Advanced profiles compose native Ixians, Tleilaxu, CHOAM and/or Richese with classic opponents and distinct required family decks. All fourteen skills and native starts remain. Auditor stays unskilled; cyborg casualties, original CHOAM support and Richese capped marker revelation remain physical. Foreign revival creates no new skill. Native Ixian Technology on Richese lots, own mixed No-Field, captured replacement, Advanced Atreides Suk/KH and unrelated overlays retain their guards.',
'Fresh three-through-six-seat Basic/Advanced development tables may compose all fourteen Leader Skills with the three original Tech Tokens: classic factions or the already-supported native Ixian, Tleilaxu, CHOAM and Richese skill rosters with their original required decks. Starting cards, cache, native skill/Traitor choices and printed or first-Storm token assignment stay genuine. Existing leader-skills and banker-income local entry preserve unused selected tokens; E3, other overlays, public activation and saved-game conversion remain separate.',
'Fresh Advanced classic or supported E1/E2 native two-through-six-seat skill tables may also retain all six original Stronghold Cards, with optional Tech at three or more seats. Original end-Mentat claims and retained local advantages remain. Arrakeen changes actual payer cost, not physical rescue or normal Banker eligibility; bank-funded support still counts in native CHOAM income. Played Carthag defenses and normal disciplines, holder-only ties and opposing-dial or played-Worthless earnings use original outcome rules. Public activation, E3/other overlays, modified Diplomat defenses and active skill/Stone interpretations stay separate.',
'Fresh three-through-six-seat Basic/Advanced development tables may compose all fourteen Skills with original Tech Tokens: classic factions, supported E1/E2 native families, or standalone Ecaz/Moritani with the exact ecaz deck and original roster exclusions. Starting cards/cache, skill/Traitor choices and printed/first-Storm assignment stay genuine. Existing leader-skills/banker-income entry preserves unused selected tokens; mixed E3 families, other overlays, public activation and saved-game conversion remain separate.',
'Fresh Advanced classic or supported native two-through-six-seat skill tables may retain six original Stronghold Cards, with Tech at three or more seats. Original end-Mentat/local held effects remain. Arrakeen changes actual payer cost, not rescue or Banker eligibility; native CHOAM income retains bank support. Physical defenses, normal disciplines, holder ties and original dial/Worthless earnings remain. Standalone Ecaz Duke and Moritani assassination compose original rules; mixed E3, allied Occupy skills, copied Diplomat defenses, active skill/Stone and other guards stay separate.',
'With this optional module, starting Treachery Cards are dealt after prediction and before skill assignment. Every faction privately receives two skills, keeps one, returns the other to the shuffled deck, and assigns its chosen card to an eligible leader. Skill and leader become public before traitor selection.',
'Before Battle Plans, leave the skilled leader face up to keep its normal effect, or move it behind the shield for possible use. A face-up leader cannot be selected for the plan. Concealing it while choosing another leader gives neither effect. A leader that must be used because no alternative remains moves behind the shield automatically.',
'Warmaster, Master of Assassins, Swordmaster of Ginaz, Killer Medic and Prana-Bindu Adept are connected. They give another leader +1 for the matching physical card role, or the surviving assigned leader +3. These bonuses do not stack to +4. They change battle strength, not the printed disc value or leader bounty.',
@@ -4621,7 +4626,7 @@ export const RULE_TOPICS: RuleTopic[] = [
{ area:'Player controls',status:'Partial',detail:'Private card/leader selection, readable inspectors, public battle posture and revival draw/decline, Planetologist range/gather controls, Special weapon selection and Suk Graduate physical rescue choices are connected. Rihani has private history and separate keep-new/reveal-old controls; automatic battle effects need no confirmation. Smuggler has explicit ordinary shipping opt-out and No-Field companion opt-in with physical-versus-priced force counts, plus automatic surviving-leader battle collection with reveal-time guidance. Banker exposes separate sealed spending and authorized inspection. Sandmaster exposes explicit legal routes, per-territory collection choices and an optional worm-destination checkbox. Diplomat offers a named committed Worthless choice or decline after public reveal, and a separate surviving-loser destination/normal/elite retreat or decline. Bureaucrat offers redirect or full payment with explicit recipient amounts and deferred bribe custody. Remaining effect controls are missing.',evidence:['components/leader-skills.tsx','components/planetologist-movement.tsx','components/suk-graduate.tsx','components/rihani-decipherer.tsx','components/mentat-question.tsx','components/bureaucrat-payment.tsx','components/leader-skill-battle-guide.tsx','components/smuggler-shipment.tsx','components/spice-banker.tsx','components/sandmaster-movement.tsx','components/sandmaster-worm.tsx','components/diplomat-defense.tsx','components/diplomat-retreat.tsx','components/game-table.tsx'] },
{ area:'AI',status:'Partial',detail:'All four profiles use private offers, legal visibility/revival actions and Planetologist movement/battle candidates and legal Suk Graduate rescues, Rihani exchanges, shared battle scoring, Smuggler reserve/owned No-Field shipments and unmodified collection plans, Sandmaster route and worm collection, funded Banker commitments and optional Diplomat copying from public revealed defenses or choosing legal losing-battle retreat. Bureaucrat uses the public payee alliance to redirect enemy income or preserve allied income. These are legal prototype paths; complete skill strategy and difficulty calibration remain unfinished.',evidence:['game/bots.ts'] },
{ area:'Documentation',status:'Partial',detail:'All fourteen faces and common rules are recorded. Skilled capture follows public physical-card custody; replacement entitlement and other material timing interpretations remain explicit.',evidence:['docs/LEADER_SKILLS_RULES.md','docs/LEADER_SKILLS_CAPTURE.md','docs/LEADER_SKILLS_RUNTIME.md','docs/PLANETOLOGIST_RULES.md','docs/SUK_GRADUATE_RULES.md','docs/LEADER_BATTLE_EFFECTS.md','docs/MENTAT_QUESTION.md','docs/BUREAUCRAT_PAYMENTS.md','docs/SMUGGLER_SHIPMENT.md','docs/SPICE_BANKER_RUNTIME.md','docs/SANDMASTER_WORM.md','docs/DIPLOMAT_DEFENSE.md'] },
{ area:'Verification',status:'Partial',detail:'Dated classic Skills/Tech evidence:25 cases,146 affected, eight genuine games (2712 actions,69 JSON continuations) and human payment/Mentat/Suk/token choice. Native Skills/Tech:52 meaningful cases, seventeen genuine3-seat games (5733 actions/no rejection,149 JSON continuations) and human typed rescue/FaceDance/marker companion. Advanced Skills/Stronghold adds21 meaningful cases,277 affected,72 final fixture-consumer cases, types/lint/build, twelve actual programs and22 genuine paired/triple games (6672 actions/no rejection,171 JSON continuations). Human390px actual bank2/own4 with trained rescue and Banker12→13 at Mentat, plus HMS declared bank1/own0/typed Suk/sole Axlotl, preserve original outcomes on refresh. Full combinations, assurance, public and deployed acceptance stay open.',evidence:['tests/leader-skills-engine.test.ts','tests/leader-skills-capture.test.ts','tests/leader-battle-effects.test.ts','tests/suk-graduate.test.ts','tests/mentat-question.test.ts','tests/bureaucrat-payment.test.ts','tests/smuggler-battle.test.ts','tests/spice-banker.test.ts','tests/advanced-native-skills.test.ts','tests/fixture-advanced-native-skills.ts','tests/skills-tech-payments-runtime.test.ts','tests/skills-tech-battle-runtime.test.ts','tests/ix-choam-skills-tech-runtime.test.ts','tests/tleilaxu-skills-tech-runtime.test.ts','tests/richese-skills-tech-runtime.test.ts','tests/classic-skills-stronghold-runtime.test.ts','tests/native-skills-stronghold-runtime.test.ts','docs/LEADER_SKILLS_RUNTIME.md'] },
{ area:'Verification',status:'Partial',detail:'Dated classic/native Skills-Tech and E1/E2 Stronghold evidence remains in the existing runtime. Standalone E3 adds15 meaningful cases,152 affected, types/lint/build, nine actual programs and eight E3 games (1531 actions/no rejection,38 JSON continuations); expanded47-game batch13936 actions/358 continuations. Human390px normal Warmaster1/Duke6/Carthag Shield wins7–6 and releases the living Duke; normal Guild Suk precedes unused Master3 death/printed bounty, original winner Tech and one private Caid at Mentat. Actual physical force/card outcomes and separately quoted Collection remain on refresh. Full combinations, assurance, public and deployed acceptance stay open.',evidence:['tests/leader-skills-engine.test.ts','tests/leader-skills-capture.test.ts','tests/leader-battle-effects.test.ts','tests/suk-graduate.test.ts','tests/mentat-question.test.ts','tests/bureaucrat-payment.test.ts','tests/smuggler-battle.test.ts','tests/spice-banker.test.ts','tests/advanced-native-skills.test.ts','tests/fixture-advanced-native-skills.ts','tests/skills-tech-payments-runtime.test.ts','tests/skills-tech-battle-runtime.test.ts','tests/ix-choam-skills-tech-runtime.test.ts','tests/tleilaxu-skills-tech-runtime.test.ts','tests/richese-skills-tech-runtime.test.ts','tests/classic-skills-stronghold-runtime.test.ts','tests/native-skills-stronghold-runtime.test.ts','tests/ecaz-skills-modules-runtime.test.ts','tests/moritani-skills-modules-runtime.test.ts','docs/LEADER_SKILLS_RUNTIME.md'] },
],
},
{