Connect Semuta in Discovery and Skills games
Verify and publish checkpoint container / container (push) Successful in 11m5s

This commit is contained in:
Quintine committed 2026-10-30 17:56:08 +11:00
1 parent 77eb2392eb
commit 528b152f7d
14 files changed
+481 -15

No files matched your search

+15 -7
View File
@@ -99,7 +99,7 @@ import { movementShipmentPreparations } from './movement-shipment-preparation';
import { MovementClaimError, liveMovementPromises, movementEventAllowed, movementPromiseModeSupported, movementPromiseTargetAvailable, settleMovementEvent, finishMovementPromises, validMovementClaim, type MovementClaim, type MovementPromise } from './movement-promises';
import { findMovementCompletion, type MovementCompletion } from './movement-promise-search';
import { classicNexusModulesProfile, mixedE1E2NexusProfile, mixedE3NexusProfile, pairedE3NexusProfile, pairedNexusModulesProfile, singleE1E2NexusProfile, standaloneE3NexusProfile } from './nexus-module-profile';
import { independentDiscoveryProfile, independentNexusProfile, nexusCoreProfile, nativeFactionTechProfile, selectedDiscoveryWithoutCardsProfile, selectedFactionStrongholdProfile, selectedIndependentCardsProfile, selectedNexusWithoutCardsProfile, selectedPhaseModuleRoster } from './faction-module-profile';
import { independentDiscoveryProfile, independentNexusProfile, nexusCoreProfile, nativeFactionTechProfile, selectedDiscoverySkillsSemutaProfile, selectedDiscoveryWithoutCardsProfile, selectedFactionStrongholdProfile, selectedIndependentCardsProfile, selectedNexusWithoutCardsProfile, selectedPhaseModuleRoster } from './faction-module-profile';
import { homeworldOccupationLeaderSkillsProfile, homeworldOccupationModulesProfile, homeworldPhaseModulesProfile } from './homeworld-module-profile';
import { RevivalPromiseError, revivalPromiseModeSupported, liveRevivalPromises, recordPromisedRevival,
revivalPromisesSatisfied, validateRevivalPromises, type RevivalClaim, type RevivalPromise } from './revival-promises';
@@ -8091,6 +8091,7 @@ function semutaHomeworldRoster(g: Game): boolean {
* Sapho's neutral simultaneous-Truth ordering in their supported parents. */
function semutaTruthOrderProfile(g: Game): boolean {
if (bareBasicSemutaProfile(g) || semutaHomeworldRoster(g)) return true;
if (selectedDiscoverySkillsSemutaProfile(g)) return true;
return g.semutaPreview === true && g.expansions.length === 1 && g.expansions[0] === 'choam' &&
!!byFaction(g, 'richese') && g.players.every(p => p.faction === 'richese' ||
p.faction === 'choam' || CLASSIC_FACTIONS[p.faction] === true) &&
@@ -11163,6 +11164,10 @@ function lobbyModulesSelected(g: Game): boolean {
/** Fresh public Richese + Skills entry, using the already connected Semuta
* continuation. Other family/module compositions retain their own entry. */
function publicSemutaSkillsProfile(g: Game): boolean {
if (g.status === 'lobby' && !g.leaderSkills && !g.homeworlds &&
!g.twoPlayerControllers && !g.shortAllianceVictory && !g.coalitionPreview &&
g.expansions.includes('choam') && !!byFaction(g, 'richese') &&
selectedDiscoveryWithoutCardsProfile(g)) return true;
return g.status === 'lobby' && typeof g.advanced === 'boolean' &&
g.players.length >= 2 && g.players.length <= 6 &&
g.expansions.length === 1 && g.expansions[0] === 'choam' && !!byFaction(g, 'richese') &&
@@ -13638,21 +13643,24 @@ function bareAdvancedEcazSemutaProfile(g: Game): boolean {
export function initializeSemutaGameForAudit(state: Game, skills = false): Game {
const basicNative = bareBasicSemutaProfile(state);
const advancedEcaz = bareAdvancedEcazSemutaProfile(state);
const selectedSkillsDiscovery = skills && state.discoveryEnabled === true && !state.homeworlds &&
selectedDiscoveryWithoutCardsProfile(state);
requireRule(!advancedEcaz || !skills, 'Advanced Ecaz Semuta excludes Leader Skills and other optional modules.');
requireRule(!state.semutaPreview &&
state.expansions.includes('choam') &&
(state.expansions.every(id => id === 'choam' || id === 'ix') || basicNative || advancedEcaz) &&
(state.expansions.every(id => id === 'choam' || id === 'ix') || basicNative || advancedEcaz || selectedSkillsDiscovery) &&
state.players.some(p => p.faction === 'richese'),
'Semuta needs a fresh Richese faction game: bare Basic selected native families, bare Advanced Ecaz/Richese, or CHOAM with optional Ix and supported original modules/skills; separate classic or Advanced Tleilax Homeworld occupation has no other modules. Other overlays remain excluded.');
if (state.discoveryEnabled) requireRule(!basicNative && !skills && !state.homeworlds &&
!state.nexusCards && discoveryModuleProfile(state),
'Semuta Discovery keeps original Richese/CHOAM and optional Ix setup, without Skills, Homeworlds, Nexus or E3 overlays.');
if (state.discoveryEnabled) requireRule(selectedSkillsDiscovery || (!basicNative && !skills && !state.homeworlds &&
!state.nexusCards && discoveryModuleProfile(state)),
'Semuta Discovery requires a supported fresh Richese roster without Homeworlds or Nexus.');
if (state.nexusCards) requireRule(!basicNative && !state.homeworlds &&
!state.discoveryEnabled && !state.discoveries,
'Semuta Nexus retains original E1/E2 rosters without Homeworlds, Discovery or E3.');
if (state.homeworlds) requireRule(!skills && semutaHomeworldRoster(state),
'Semuta Homeworlds require original Richese/CHOAM and classic factions with exact CHOAM, or Advanced Tleilax with exact CHOAM+Ix, and no other modules.');
const g = state.discoveryEnabled ? initializeDiscoveryGameForAudit(state)
const g = selectedSkillsDiscovery ? initializeLeaderSkillsGameForAudit(state)
: state.discoveryEnabled ? initializeDiscoveryGameForAudit(state)
: state.homeworlds ? initializeHomeworldOccupationGameForAudit(state)
: skills ? initializeLeaderSkillsGameForAudit(state)
: state.nexusCards ? state.expansions.length === 1 && !!byFaction(state, 'choam')
@@ -25185,7 +25193,7 @@ function arrivalOverlapModeSupported(g: Game, revivalArrival?: RevivalEntryParen
if (bareBasicNativeArrivalOverlap(g)) return true;
if (bareAdvancedNativeArrivalOverlap(g)) return true;
if (e3DiscoveryOnlyOverlapProfile(g)) return true;
if (g.leaderSkills && selectedDiscoveryWithoutCardsProfile(g) &&
if (g.leaderSkills && (selectedDiscoveryWithoutCardsProfile(g) || selectedDiscoverySkillsSemutaProfile(g)) &&
byFaction(g, 'ecaz') && byFaction(g, 'moritani')) return true;
if (homeworldPhaseModulesProfile(g) && byFaction(g, 'ecaz') && byFaction(g, 'moritani')) return true;
if (revivalArrival && g.homeworlds && byFaction(g, 'ecaz') && byFaction(g, 'moritani')) return true;